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
相关产品推荐
相关产品推荐

