Node.js服务器Firebase Admin SDK自定义令牌生成及ID Token验证问题
解决Firebase Admin SDK ID Token验证失败及后续FCM发送问题
看起来你在首次使用Firebase Admin SDK时遇到了ID Token验证的瓶颈,我帮你一步步拆解问题、排查解决:
1. 先获取具体错误信息(最关键的第一步)
你当前的catch块只打印了Error receiving tokens,完全看不到验证失败的具体原因(比如Token无效、过期、签名不匹配等),这根本没法精准定位问题。先修改这段代码,把错误对象完整打印出来:
.catch(function(error) { console.log("Error receiving tokens: ", error); // 新增打印error对象,获取详细日志 });
运行后你就能看到像invalid_token、token_expired这类具体提示,这是解决问题的核心依据。
2. 排查ROT13解密的正确性
你用rot(req.params.idToken, -13)解密ID Token,需要先确认两个点:
- 客户端确实是用ROT13(位移13位)加密后再传递的吗?如果客户端加密方式不对,解密后的Token就是无效的,自然验证失败。
- 手动测试
rot模块的正确性:拿一个已知的有效ID Token用ROT13加密,再用你的解密代码还原,看是否和原Token一致,确保模块的位移方向和参数使用正确。
3. ID Token验证的常见坑点
3.1 服务账号与初始化正确性
- 确认
serviceAccount对应的JSON文件是从Firebase控制台正确下载的(项目设置>服务账号>生成新的私钥),文件路径没有错误。 - 给Admin SDK初始化加个错误捕获,确保初始化本身没有问题:
try { admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://skill-india-3e512.firebaseio.com/" }); console.log("Firebase Admin SDK初始化成功"); } catch (err) { console.log("Admin SDK初始化失败: ", err); }
3.2 ID Token的有效性
- ID Token必须是从Firebase Auth客户端SDK(比如Web端的
firebase.auth().currentUser.getIdToken())获取的,不能是自定义生成的字符串。 - ID Token有1小时的有效期,过期后会验证失败,需要客户端重新获取。
- 确保你的Admin SDK项目和客户端使用的是同一个Firebase项目,否则Token签名会不匹配。
4. 提前修复FCM发送的代码错误
就算ID Token验证通过,你当前的FCM代码还有几个语法和格式错误,提前帮你踩坑:
4.1 语法错误:messaging调用的逗号
你写了admin.messaging(),sendToDevice(...),这里的逗号是错误的,应该用点调用方法:
admin.messaging().sendToDevice(registrationToken, payload, options)
4.2 Payload格式错误
FCM的消息payload格式不符合要求,$sceDelegate是Angular的内部服务,不该出现在这里,正确的data格式应该是:
var payload = { data: { MyKey1: customToken } };
4.3 拼写错误:timeToLive
你写的tmeToLive是拼写错误,正确的参数名是timeToLive:
var options = { priority: "high", timeToLive: 60 * 60 * 24 };
5. 调试建议
- 先本地直接测试:不用ngrok,用Postman等工具在本地发起GET请求,传递未加密的有效ID Token,看验证是否成功,排除ngrok或客户端加密的问题。
- 确认请求参数是否正确接收:在解密前先打印原始参数,确保
req.params能拿到正确的值:
console.log("请求原始idToken: ", req.params.idToken); console.log("请求原始registrationToken: ", req.params.registrationToken);
按照上面的步骤一步步排查,先解决ID Token验证的具体错误,再处理FCM的问题,应该就能顺利跑通了。
内容的提问来源于stack exchange,提问作者Shubham Gupta




