【问题标题】:Firebase cloud functions - Error: Reference.child failed: First argument was an invalid pathFirebase 云函数 - 错误:Reference.child 失败:第一个参数是无效路径
【发布时间】:2020-12-21 14:41:18
【问题描述】:

我正在尝试使用本教程获取推送通知:https://www.youtube.com/watch?v=z27IroVNFLI

它显然有点老了,但 Firebase 网络应用没有很多好的替代品。

我的云功能运行时出现以下错误:

fcm发送

错误:Reference.child 失败:第一个参数是无效路径 =“/fcmTokens/[object Object]”。路径必须是非空字符串,并且在 validatePathString (/srv/node_modules/@firebase/database/dist/index.node) 中不能包含“.”、“#”、“$”、“[”或“]” .cjs.js:1636:15) 在 validateRootPathString (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:1647:5) 在 Reference.child (/srv/node_modules/@firebase/database /dist/index.node.cjs.js:13688:17) 在 Database.ref (/srv/node_modules/@firebase/database/dist/index.node.cjs.js:14862:48) 在 exports.fcmSend.functions .database.ref.onWrite (/srv/index.js:21:12) 在 cloudFunction (/srv/node_modules/firebase-functions/lib/cloud-functions.js:131:23) 在 /worker/worker.js: 825:24 at process._tickDomainCallback (internal/process/next_tick.js:229:7)

这里是云功能:

exports.fcmSend = functions.database
                           .ref('/model_outputs/real_estate')
                           .onWrite((change, context) => {

    const userId  = change.after.val();
    console.log(change);
    const payload = {
          notification: {
            title: "test",
            body: "test body",
            icon: "https://placeimg.com/250/250/people"
          }
        };
  
  
     admin.database()
          .ref(`/fcmTokens/${userId}`)
          .once('value')
          .then(token => token.val() )
          .then(userFcmToken => {
            return admin.messaging().sendToDevice(userFcmToken, payload)
          })
          .then(res => {
            console.log("Sent Successfully", res);
            return null;
          })
          .catch(err => {
            console.log(err);
          });
  
  });

我已经看到其他人发布了有关此错误的帖子,但是当他们使用 's 而不是 s in this case: admin.database().ref(/fcmTokens/${userId})` 时,他们中的大多数人不得不这样做。如您所见,我使用的是刻度,所以我不确定这里出了什么问题。

以下是我的数据库中的数据结构:

显然,我砍掉了 ID,但我只是想说明它直接嵌套在 /fcmTokens 下。

【问题讨论】:

  • 您需要显示有关数据库结构的更多详细信息。 /model_outputs/real_estate 在哪里? const userId = change.after.val(); console.log(userId); 有什么用?
  • @RenaudTarnec /model_outputs/ 在我的数据库的顶层。所以,基本上,我希望在/real_estate 下的任何内容被写入时发生通知。我在console.log 中添加了userID,出现了一个错误,说是未定义。

标签: node.js firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

你的云函数好像有几个问题:

#1

以下行会产生错误,因为userId 不是字符串。

admin.database().ref(`/fcmTokens/${userId}`)

'/model_outputs/real_estate' 处的 DB 节点的值很可能是一个对象,因此当您执行 const userId = change.after.val(); 时,您将一个对象分配给 userId

根据您的上述评论进行更新:您似乎得到了undefineduserId。你需要调试并解决这个问题:它必须是一个字符串。

#2

以下承诺链是错误的:

admin.database()
      .ref(`/fcmTokens/${userId}`)
      .once('value')
      .then(token => token.val() )  // You don't return anything here, and not a Promise
      .then(userFcmToken => {
        return admin.messaging().sendToDevice(userFcmToken, payload)
      })
      .then(res => {
        console.log("Sent Successfully", res);
        return null;
      })
      .catch(err => {
        console.log(err);
      });

如果我正确理解您的逻辑和数据模型,它应该是以下几行:

admin.database()
      .ref(`/fcmTokens/${userId}`)
      .once('value')
      .then(snapshot => { 
        const userFcmToken = snapshot.val();
        return admin.messaging().sendToDevice(userFcmToken, payload)
      })
      .then(res => {
        console.log("Sent Successfully", res);
        return null;
      })
      .catch(err => {
        console.log(err);
      });

【讨论】:

  • 我很抱歉,我非常缺乏经验。所以,我认为我执行不正确。我刚刚意识到,在教程中,他将用户 ID 存储在推送到数据库的每条消息中。然后他说存储在/fcmTokens/ 中的用户ID 我的最终目标是在数据库更新时向所有用户发送通知。在我的情况下,用户 ID 字符串无关紧要。这样的实施是否需要进行重大更改?
  • 如果您想向多个设备发送消息,您需要发送至topicmulti devices
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 2017-12-01
相关资源
最近更新 更多