简体   繁体   English

Firebase 实时数据库订单按孩子与大多数孩子

[英]Firebase realtime database order by child with most children

I have a database which allows users to 'like' comments given on posts.我有一个数据库,允许用户“喜欢”帖子上的评论。

When I originally fetch the comments, is there a way to order comments by 'highest' liked first?当我最初获取评论时,有没有办法按照“最高”喜欢的方式对评论进行排序?

Now I know I could do .orderByChild() but the problem is I don't have a 'like' value child.现在我知道我可以做.orderByChild()但问题是我没有“喜欢”价值的孩子。

The way I process 'likes' is to save the users UID and timestamp inside the original commentID child.我处理“喜欢”的方式是将用户 UID 和时间戳保存在原始评论 ID 子项中。

Is it possible to fetch comments based on the child with the most children inside?是否可以根据里面孩子最多的孩子来获取评论?

My database looks like:我的数据库看起来像:

{
 "users" : {
  "$uid" : {
   "posts" : {
    "$postID" : {
     "postText" : "blah blah blah",
      "comments" : {
       "$commentID" : {
        "commentText" : "blah blah blah",
         "likes" : {
          "UID01" : "1622035190516",
          "UID02" : "1622036141955",
          "UID03" : "1622036145134",
         }
       },
       "$commentID" : {
        "commentText" : "blah 2 blah 2 blah 2",
         "likes" : {
          "UID01" : "1622036141955",
          "UID02" : "1622036145134",
         }
       }
      }
    }
   }
  }
 }
}

Is it possible to fetch comments based on the child with the most children inside?是否可以根据里面孩子最多的孩子来获取评论?

No you cannot sort data based on an aggregation calculated on the fly.不,您不能根据动态计算的聚合对数据进行排序

One classical solution for this case in the NoSQL world is to maintain a counter. NoSQL 世界中这种情况的一个经典解决方案是维护一个计数器。 One of the best approaches for that is to use a Cloud Function : the calculation is done in the backend via the Admin SDK and therefore you can protect the database nodes containing the number of likes with a security rule in such a way the users cannot modify their values.最好的方法之一是使用云 Function :计算是通过管理员 SDK 在后端完成的,因此您可以使用安全规则保护包含喜欢数量的数据库节点,这样用户就无法修改他们的价值观。


More concretely, you should:更具体地说,您应该:

1/ Initialize the counter to 1 when you write the first like. 1/ 写第一个like时将计数器初始化为1。 You would use an onCreate Cloud Function along the following lines:您将按照以下几行使用 onCreate Cloud Function:

exports.initializeCounter = functions.database.ref('users/{uid}/posts/{postID}/comments/{commentID}/likes')
    .onCreate((snapshot, context) => {
      return snapshot.ref.parent.child('nbrOfLikes').set(1);
    });

2/ Update the counter each time you add or remove a like with an onUpdate Cloud Function in which you count the nbr of likes and update the counter accordingly. 2/ 每次使用 onUpdate Cloud Function 添加或删除喜欢时更新计数器,您可以在其中计算喜欢的 nbr 并相应地更新计数器。 The following Cloud Function will do the job.以下 Cloud Function 将完成这项工作。

exports.updateCounter = functions.database.ref('users/{uid}/posts/{postID}/comments/{commentID}/likes')
    .onUpdate((change, context) => {
        const likeObject = change.after.val();
        return change.after.ref.parent.child('nbrOfLikes').set(Object.keys(likeObject).length);
    });

You could alternatively use the numChildren() method, see this answer .您也可以使用numChildren()方法,请参阅此答案


Note that you would need to treat the case where all the likes are deleted, if this case happens in your app.请注意,如果这种情况发生在您的应用中,您需要处理删除所有喜欢的情况。


Note also that the two (or three) Cloud Functions could be merged in one onWrite Cloud Function.另请注意,两个(或三个)云功能可以合并为一个 onWrite Cloud Function。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM