Laravel集成FCM推送通知提示注册令牌无效问题排查
Laravel FCM推送数据库读取令牌失效修复
问题根因
- 变量使用错误:数据库查询代码中调用了未定义的
$user变量,routeNotificationForFcm是User模型的实例方法,当前实例对应的用户ID应当通过$this->id获取,错误的变量会导致查询条件失效,拿到错误的令牌数据。 - 格式不满足FCM要求:
pluck()方法默认返回Laravel集合对象,且数据库中存储的令牌可能携带首尾空格、换行符等不可见字符,只要令牌存在多余字符,就会被FCM判定为无效。 - 无效令牌未过滤:查询逻辑没有剔除空值、已过期、已作废(用户卸载APP、重置设备后产生的失效令牌)的记录,返回结果中只要混入一个无效令牌,就会抛出对应错误。
修复方案
推荐写法(通过模型关联实现)
- 先在User模型中定义和设备令牌表的关联:
// App\Models\User.php public function fcmTokens() { return $this->hasMany(\App\Models\FcmToken::class); }
- 修正
routeNotificationForFcm方法逻辑,做好格式清洗和无效值过滤,最终返回纯数组:
public function routeNotificationForFcm() { return $this->fcmTokens() ->pluck('device_token') ->map(fn($token) => trim($token)) // 清除令牌首尾的空白、换行等不可见字符 ->filter(fn($token) => filled($token)) // 过滤空令牌 ->values() ->toArray(); }
无模型临时写法
如果暂时不想创建FcmToken模型,直接查询表的话按如下方式修正,注意替换掉错误的$user->id:
public function routeNotificationForFcm() { return \DB::table('fcm_tokens') ->where('user_id', $this->id) ->pluck('device_token') ->map(fn($token) => trim($token)) ->filter() ->toArray(); }
额外排查点
如果修正代码后仍报错,可先打印该方法的返回值,和你之前硬编码的正常令牌做逐字符比对,确认是否存在不可见字符;同时建议定期清理表中已被FCM标记为失效的旧令牌,避免无效数据混入推送列表。
内容的提问来源于stack exchange,提问作者Affar
相关产品推荐
相关产品推荐

