Google Cloud Functions中调用数组splice方法遇TypeError问题求助
解决Firestore云函数中splice的TypeError问题
我来帮你排查这个问题!你遇到的TypeError主要有几个潜在原因,咱们逐个解决:
核心问题分析
registrationTokens可能不是数组:从Firestore读取的token字段如果是单个字符串(而非数组),调用数组方法indexOf和splice就会触发错误。- 数组引用与初始化问题:
const stillRegisteredTokens = registrationTokens是直接引用原变量,如果原变量不是数组,后续操作自然报错。 - Firestore文档路径错误:更新文档时的路径少了必要的斜杠,会导致找不到目标文档。
- 小笔误:代码里的
new mage message应该是new image message,虽然不影响功能,但还是修正下更严谨。
修复后的完整代码
const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(); exports.notifyNewMessage = functions.firestore.document('users/{ID}/contacts/{contactID}/messages/{messageID}') .onCreate((docSnapshot, context) => { const message = docSnapshot.data(); const recipientId = message['recipientId']; const senderId = message['sender']; const senderName = message['senderName']; // 读取用户的token文档 return admin.firestore().doc(`users/${recipientId}/token/token`).get().then(userDoc => { // 确保获取到的token是数组:如果是单个字符串转数组,为空则初始化空数组 let registrationTokens = userDoc.get('token'); if (!Array.isArray(registrationTokens)) { registrationTokens = registrationTokens ? [registrationTokens] : []; } const notificationBody = (message['data_type'] === "TEXT") ? message['message'] : "You received a new image message."; const payload = { notification: { title: `${senderName} sent you a message.`, body: notificationBody, clickAction: "MessageListActivity" }, data: { USER_NAME: senderName, USER_NUMBER: message['sender'] } }; return admin.messaging().sendToDevice(registrationTokens, payload).then(response => { // 创建原数组的副本,避免直接修改原数组,同时保证是数组类型 const stillRegisteredTokens = [...registrationTokens]; response.results.forEach((result, index) => { const error = result.error; if (error) { const failedRegistrationToken = registrationTokens[index]; console.error('failed token ', failedRegistrationToken, error); if (error.code === 'messaging/invalid-registration-token' || error.code === 'messaging/registration-token-not-registered') { const failedIndex = stillRegisteredTokens.indexOf(failedRegistrationToken); if (failedIndex > -1) { stillRegisteredTokens.splice(failedIndex, 1); } } } }); // 修复文档路径:用模板字符串确保斜杠正确 return admin.firestore().doc(`users/${recipientId}/token/token`).update({ token: stillRegisteredTokens // 字段名和读取时保持一致,原代码的registrationTokens是笔误 }); }); }); });
关键修复点说明
- 强制数组类型:增加
Array.isArray判断,把单个令牌字符串转为数组,空值则初始化空数组,从根源避免数组方法报错。 - 数组副本操作:用扩展运算符
[...registrationTokens]创建原数组的独立副本,既不影响原数据,也保证stillRegisteredTokens一定是数组。 - 路径修正:使用模板字符串拼接文档路径,确保斜杠位置正确,避免Firestore找不到目标文档。
- 字段名统一:更新Firestore时的字段名改为
token,和读取时的字段名保持一致,原代码的registrationTokens是笔误。
这样修改后,应该就能解决splice的TypeError问题了,同时也修复了一些潜在的逻辑漏洞。
内容的提问来源于stack exchange,提问作者martinseal1987
相关产品推荐
相关产品推荐

