首页 > 解决方案 > firebase 云消息不发送推送通知 - 参数“值”的值不是有效的查询约束

问题描述

我将以下 FCM 推送通知推送到 firebase 函数:

import * as functions from 'firebase-functions';

import * as admin from 'firebase-admin';

admin.initializeApp();

exports.newSubscriberNotification = functions.firestore
    .document('messages/{id}')
    .onUpdate(async event => {
        const data = event.after.data();
        const content = data ? data.content : '';
        const toUserId = data ? data.toUserId : '';

        const payload = {
            notification: {
                title: 'New message',
                body: `${content}`
            }
        };

        const db = admin.firestore();
        const devicesRef = db.collection('devices').where('userId', '==', toUserId);

        const devices = await devicesRef.get();
        const tokens: any = [];

        devices.forEach(result => {
            const token = result.data().token;
            tokens.push(token);
          });

        return admin.messaging().sendToDevice(tokens, payload);
    });

在我使用.onUpdate 的代码中,我假设它应该在更新消息集合之一时触发。这是一个消息应用程序,所以每当消息集合更新时,我想触发一个推送通知给接收用户。

我得到 tuUserId 并使用它从设备集合中获取该用户的设备令牌。我现在正在测试,所以 toUserId 与 from userId 相同,因为它只是在使用我的设备......所以希望当我更新 message.doc() 时它会发送推送通知。

这是firebase中的消息集合:

在此处输入图像描述

这是函数错误日志:

11:04:22.937 PM
newSubscriberNotification
Function execution started
11:04:22.946 PM
newSubscriberNotification
Error: Value for argument "value" is not a valid query constraint. Cannot use "undefined" as a Firestore value.
    at Object.validateUserInput (/srv/node_modules/@google-cloud/firestore/build/src/serializer.js:273:15)
    at validateQueryValue (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:1844:18)
    at CollectionReference.where (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:956:9)
    at exports.newSubscriberNotification.functions.firestore.document.onUpdate (/srv/lib/index.js:19:49)
    at cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23)
    at /worker/worker.js:825:24
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)
11:04:22.957 PM
newSubscriberNotification
Function execution took 21 ms, finished with status: 'error'

我很确定它不喜欢我的 .where 子句,因为这个错误:在 CollectionReference.where (/srv/node_modules/@google-cloud/firestore/build/src/reference.js:956:9)

我只是不知道为什么

标签: typescriptgoogle-cloud-firestoregoogle-cloud-functions

解决方案


屏幕截图中的文档包含一组对象,您的代码无法处理这些对象。您正在尝试toUserId从文档的根目录读取它不存在的位置。这意味着您toUserId的值为undefined,Firestore 抱怨此值。

在单个文档中看到多个对象/消息有点不寻常,因此您必须确定这是否真的是最好的方法。但如果是,您将必须确定要将通知发送到这些对象中的哪一个。如果你想发送到所有这些对象,你可以遍历它们:

exports.newSubscriberNotification = functions.firestore
.document('messages/{id}')
.onUpdate(async event => {
  const allMessages = event.after.data();
  const db = admin.firestore();

  Object.keys(allMessages).forEach((index) => {
    let data = allMessages[index];

    const content = data ? data.content : '';
    const toUserId = data ? data.toUserId : '';

    const payload = {
        notification: {
            title: 'New message',
            body: `${content}`
        }
    };

    const devicesRef = db.collection('devices').where('userId', '==', toUserId);

    const devices = await devicesRef.get();

    ...
  })
});

推荐阅读