搜索某个节点下是否存在特定的 children

Search for existence of specific children under a node

我正在使用 Firebase 实时数据库Cloud Functions 开发聊天应用。我有一个节点 members,我在其中存储每个聊天室中每个用户的 ID:

我想要实现的(目前效率不高)是检查,例如,user1randomUid1)是否有以最有效的方式与 user2(使用 randomUid2)进行主动聊天。我想出的唯一解决方案是下载整个节点 (/members) 并检查数据快照的每个 child,如果两个 uids 存在。提前致谢。

是的,您必须全部检查。我认为这不会成为问题,因为您的聊天记录可能低于 100k 左右。

因为我不知道你使用的数据结构,我只是根据你的图像尝试一下,你必须适应你的结构。

// assuming a reasonable structure
let chats = [{name: "chat1", "1": true, "5": true}, {name: "chat2", "1": true, "2": true}];

function hasChat(chats, uid1, uid2) {
    return chats.find((chat) => {
        let uids = Object.keys(chat);
        return uids.indexOf(uid1) !== -1 && uids.indexOf(uid2) !== -1;
    }) !== undefined;
}

console.log(hasChat(chats, "1", "2"));

这可以通过使用库来提高性能和可读性。

以下实施工作。但是如果没有索引,它最终会下载 members 节点下的所有内容,并在客户端过滤数据:

const ref = admin.database().ref('members');
const snap1 = await ref.orderByChild('user1').equalTo(true).once('value');
const user1Chats = Object.keys(snap1.val());

const snap2 = await ref.orderByChild('user2').equalTo(true).once('value');
const user2Chats = Object.keys(snap2.val());

user1Chats.forEach((chat) => {
  if (user2Chats.indexOf(chat) >= 0) {
    console.log('Chat in common:', chat);
  }
});

SDK 将记录以下警告:

@firebase/database: FIREBASE WARNING: Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "user1" at /members to your security rules for better performance. 

您还可以尝试存储每个用户的聊天记录(除了您已有的):

user1
  |
   -- chat1: true
   -- chat2: true

user2
  |
   -- chat2: true
   -- chat3: true

那么只需要查询两个用户节点,并检查它们是否有任何重叠(上例中的chat2)。如果您的应用程序中的聊天室数量随着时间的推移无限制地增长,此解决方案将在长期 运行 中表现更好。希望每个用户的聊天次数远小于整个应用程序中活跃聊天的总数。