NodeJS中Firebase Admin SDK初始化报undefined如何解决
问题现象
尝试运行代码完成Firebase Admin SDK初始化、实现通知消息发送功能,代码如下:
const admin = require('firebase-admin/app'); const errorCodes = require('source/error-codes'); const PropertiesReader = require('properties-reader'); const prop = PropertiesReader('properties.properties'); exports.sendSingleNotification = async (event, context) => { const params = event.queryStringParameters; var serviceAccount = require("xxx-xxx-firebase-adminsdk-xxx-xxx.json"); try { admin.initializeApp({ credential: admin.credential.cert(serviceAccount) }); console.log("INITIALIZED"); // This registration token comes from the client FCM SDKs. const registrationToken = params.fcmtoken; console.log() const message = { notification: { title: 'FooCorp up 1.43% on the day', body: 'FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.' }, token: registrationToken }; // Send a message to the device corresponding to the provided // registration token. admin.getMessaging().send(message) .then((response) => { // Response is a message ID string. console.log('Successfully sent message:', response); return {"response":response} }) .catch((error) => { console.log('Error sending message:', error); return {"error 1":error} }); } catch (error) { console.log(error); return {"error 2":error} } };
代码中serviceAccount指向项目根目录存放的Firebase私钥文件,运行时始终抛出如下错误:
START RequestId: e66ffdd9-ab9c-4a68-ade2-7cfa97f42c31 Version: $LATEST at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)] (/var/task/source/fcm/send-single-notification.js:14:42)rt' of undefined END RequestId: e66ffdd9-ab9c-4a68-ade2-7cfa97f42c31
错误提示存在取值为undefined的对象,无法定位具体出错位置与根因。
根本原因
报错里截断显示的'rt' of undefined实际对应代码第14行的admin.credential.cert调用,核心问题有4个:
- 模块导入错误:只导入了
firebase-admin/app入口模块,该模块本身不挂载credential、getMessaging方法,这两个方法分别需要从firebase-admin/app导出credential、单独导入firebase-admin/messaging模块才能使用,直接调用时admin.credential本身就是undefined,自然会抛出属性访问错误。 - 初始化位置错误:
admin.initializeApp写在函数内部,函数第二次触发时会重复执行初始化,直接抛出应用已存在的错误。 - 异步逻辑未等待:在async函数中使用
.then()链式调用发送消息,但没有加await,函数会在消息发送逻辑执行完成前提前返回,导致发送流程被中断。 - 缺少参数校验:没有判断
event.queryStringParameters、params.fcmtoken是否存在,对应参数缺失时也会触发undefined错误。
修复步骤
- 修正导入语句,补充引入credential和messaging模块
- 将SDK初始化逻辑移到函数外部,全局只执行一次
- 给消息发送逻辑加
await,统一用async/await处理异步流程,去掉冗余的.then/.catch - 补充基础参数校验,避免空值访问
修复后的完整代码:
// 修正导入 const { initializeApp, cert } = require('firebase-admin/app'); const { getMessaging } = require('firebase-admin/messaging'); const errorCodes = require('source/error-codes'); const PropertiesReader = require('properties-reader'); const prop = PropertiesReader('properties.properties'); const serviceAccount = require("xxx-xxx-firebase-adminsdk-xxx-xxx.json"); // 初始化移到函数外,全局只执行一次 initializeApp({ credential: cert(serviceAccount) }); exports.sendSingleNotification = async (event, context) => { try { // 加参数校验 const params = event.queryStringParameters; if (!params || !params.fcmtoken) { return {"error": "missing fcm token parameter"} } const registrationToken = params.fcmtoken; const message = { notification: { title: 'FooCorp up 1.43% on the day', body: 'FooCorp gained 11.80 points to close at 835.67, up 1.43% on the day.' }, token: registrationToken }; // 等待异步发送完成 const response = await getMessaging().send(message) console.log('Successfully sent message:', response); return {"response":response} } catch (error) { console.log('Error sending message:', error); return {"error": error} } };
注意:如果部署环境是Lambda等Serverless服务,要确认私钥json文件确实被打包到了部署产物中,路径引用和部署后的文件路径一致,否则也会出现require加载失败的问题。
内容的提问来源于stack exchange,提问作者PeakGen
相关产品推荐
相关产品推荐

