You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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是笔误
            });
        });
    });
});

关键修复点说明

  1. 强制数组类型:增加Array.isArray判断,把单个令牌字符串转为数组,空值则初始化空数组,从根源避免数组方法报错。
  2. 数组副本操作:用扩展运算符[...registrationTokens]创建原数组的独立副本,既不影响原数据,也保证stillRegisteredTokens一定是数组。
  3. 路径修正:使用模板字符串拼接文档路径,确保斜杠位置正确,避免Firestore找不到目标文档。
  4. 字段名统一:更新Firestore时的字段名改为token,和读取时的字段名保持一致,原代码的registrationTokens是笔误。

这样修改后,应该就能解决splice的TypeError问题了,同时也修复了一些潜在的逻辑漏洞。

内容的提问来源于stack exchange,提问作者martinseal1987

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:16:58