You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel通过Firebase发送OTP:如何获取用户设备令牌?

要通过FCM给用户发送OTP,核心是让客户端先生成FCM令牌,再将令牌与手机号一同传给后端——因为FCM令牌是由客户端设备生成的,后端无法直接获取。具体操作步骤如下:

1. 客户端生成并上传FCM令牌

根据你的客户端类型(网页/移动端),使用对应Firebase SDK获取令牌:

网页端(Web)实现

在前端页面引入Firebase JS SDK后,添加以下代码获取并上传令牌:

// 初始化Firebase后
const messaging = getMessaging();

// 请求用户授权通知权限
Notification.requestPermission().then((permission) => {
  if (permission === 'granted') {
    // 获取FCM令牌
    getToken(messaging, { vapidKey: '你的VAPID密钥' }).then((currentToken) => {
      if (currentToken) {
        // 用户输入手机号后,将令牌与手机号一起传给后端请求发送OTP
        fetch('/send-otp', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ phone: '用户输入的手机号', fcm_token: currentToken })
        });
      } else {
        // 令牌获取失败,降级使用短信发送OTP
      }
    });
  }
});

// 监听令牌刷新事件,及时更新后端存储的令牌
onTokenRefresh(() => {
  getToken(messaging).then((refreshedToken) => {
    fetch('/update-fcm-token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ phone: '用户手机号', fcm_token: refreshedToken })
    });
  });
});

移动端(Android/iOS)实现

以Android为例,使用Firebase Messaging SDK获取令牌:

// 在Activity或Service中调用
FirebaseMessaging.getInstance().token.addOnCompleteListener { task ->
  if (!task.isSuccessful) {
    return@addOnCompleteListener
  }
  // 获取到的FCM令牌
  val token = task.result
  // 将令牌与手机号通过接口传给后端
}

// 监听令牌刷新,同步更新后端数据
FirebaseMessaging.getInstance().token.addOnTokenRefreshListener { refreshedToken ->
  // 调用后端接口更新令牌
}

2. 后端修改逻辑,接收并使用令牌

修改你的sendOTP函数,接收客户端传来的FCM令牌,绑定到OTP记录后发送消息:

public function sendOTP(Request $request)
{
    $phone = $request->input('phone');
    $registrationToken = $request->input('fcm_token'); // 从请求中获取客户端传的令牌

    $code = $this->generateOTPCode();

    // 存储OTP时同步保存FCM令牌(需在AuthOTP表新增fcm_token字段)
    $auth_otp = AuthOTP::create([
      'phone' => $phone,
      'code' => $code,
      'status' => BaseConstants::STATUS_INACTIVE,
      'fcm_token' => $registrationToken
    ]);

    if ($auth_otp && $registrationToken) {
      $messaging = app('firebase.messaging');
      $message = CloudMessage::withTarget('token', $registrationToken)
        ->withNotification(Notification::create('Mã xác thực OTP', "Mã xác thực của bạn là: $code"))
        ->withData(['otp_code' => $code]);

      try {
        $messaging->send($message);
      } catch (\Exception $e) {
        // FCM发送失败时,降级使用短信服务发送OTP
        // $this->sendSMS($phone, $code);
      }
    }
    return $auth_otp;
}

关键注意事项

  • 若用户未授权通知权限(网页端)或设备无法获取FCM令牌,必须准备短信发送的降级方案,避免用户收不到OTP。
  • FCM令牌会定期刷新,客户端需监听刷新事件并同步更新后端存储的令牌,保证后续消息推送有效。
  • 建议单独创建device_tokens数据表,关联用户手机号/ID存储有效令牌,方便后续其他消息推送场景使用。

内容的提问来源于stack exchange,提问作者Minh Tuấn Nguyễn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:37:04