【问题标题】:How to update Array field?如何更新数组字段?
【发布时间】:2018-06-23 08:58:54
【问题描述】:

我正在使用 Firebase Firestore,并希望使用最新聊天线程的 id 更新用户配置文件下的数组字段。我猜我必须从该用户下的聊天节点中提取整个数组(如果存在),然后我需要附加新的 id(如果它不存在)并更新数组。当数组中只有 1 个值时它可以工作,然后它会失败并出现以下错误:

事务失败:{ 错误:无法将数组值转换为数组值。 在 /user_code/node_modules/firebase-admin/node_modules/grpc/src/node/src/client.js:554:15 代码:3,元数据:元数据 { _internal_repr: {} } }

这是我的firebase云功能,谁能告诉我哪里出错了?

  exports.updateMessages = functions.firestore.document('messages/{messageId}/conversation/{msgkey}').onCreate(  (event) => {
    /// console.log('function started');
    const messagePayload = event.data.data();
    const userA = messagePayload.userA;
    const userB = messagePayload.userB;     
    // console.log("userA " + userA);
    // console.log("userB " + userB);  
    // console.log("messagePayload " + JSON.stringify(messagePayload, null, 2) );    

  const sfDocRef = admin.firestore().doc(`users/${userB}`);

  return admin.firestore().runTransaction( (transaction) => {

      return transaction.get(sfDocRef).then( (sfDoc) => {

          const array = [];
          array.push(...[event.params.messageId, sfDoc.get('chats') ]);

          transaction.update(sfDocRef, { chats: array } ); 

      });
  }).then( () => {
      console.log("Transaction successfully committed!");
  }).catch( (error) => {
      console.log("Transaction failed: ", error);
  });  

  });

【问题讨论】:

  • 这是 Firebases 建议不要将数据存储在数组中的原因之一。您当前的数据看起来像一组更好,如下所示:firebase.google.com/docs/firestore/solutions/arrays。这样添加聊天 ID 就像 sfDocRef.update({ "chats."+event.params.messageId, true }) 一样简单。

标签: javascript firebase google-cloud-functions google-cloud-firestore firebase-admin


【解决方案1】:

我已进一步调查此事,我会遵循弗兰克在他的帖子中给你的建议;在集合而不是数组中分配数据,因为它们对 Firebase 1 具有更大的多功能性。通过研究 Firebase 网站中列出的示例,寻找与聊天相关的任何内容,我发现了 Firechat 使用的消息的数据结构和代码,因为它们可能对您有用。

在源代码中,他们为他们的 message-id -userId 对使用了一个集合,该集合具有以下拓扑2

在存储库中执行保存的确切方式是 3

它将消息附加到 Room-id 集合中。您可以使用 userID - messageID 对来代替这种结构,因为它可能更适合您。

【讨论】:

    【解决方案2】:

    您在这里的代码中嵌套了数组:

    const array = [];
    array.push(...[event.params.messageId, sfDoc.get('chats') ]);
    

    这导致array 有两个值,第一个是新的messageId,第二个值包含一个数组,其中包含您以前的所有值,例如

    [ "new message id", ["previous id", "older id"] ]
    

    这种类型的嵌套数组是 Firestore(显然)不允许存储的东西。

    解决方法很简单:

    const array = [event.params.messageId, ...sfDoc.get('chats')];
    

    您必须先加载数组,然后再向其中添加单个元素,这也是 Firebases 建议不要将数据存储在数组中的原因之一。您当前的数据看起来最好作为一个集合,如the Firestore documenation所示:

    {
      "new message id": true, 
      "previous id": true, 
      "older id": true
    }
    

    这样添加聊天 ID 就这么简单:

    sfDocRef.update({ "chats."+event.params.messageId, true })
    

    【讨论】:

    • 谢谢弗兰克,虽然我有你在这里。这是在 Firestore 中布置聊天应用程序的正确方法吗?我的想法是将聊天 id 存储在用户节点下,然后在主消息收件箱中获取这些 id 并使用它们来引用带有所有单独消息的消息节点。这对我来说似乎违反直觉,但我想不出使用 Firestore 的更优化方法
    • 对我来说听起来很合理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-22
    相关资源
    最近更新 更多