如何使用 firebase 在未指定的键中检索按键排序的数据

how to retrieve data ordered by key inside unspecified key with firebase

我在 firebase 中有一个快照供参考,如下所示:

"friendlist" : {
    "user1" : {
        "user3" : 1
    },
    "user2" : {
        "user1" : 0
    }
    "user3" : {
        "user1" : 1
    }
}

参考解释:

每个用户都有一个唯一的 ID,我使用用户的 ID 作为他们朋友列表的唯一 ID。在上面的示例中,我有 3 个用户,每个用户都有自己的好友列表。在他们的好友列表中,有其他用户的 id 已经与他成为好友。如果值为1,则该用户已经是好友。但是当值为0时,用户请求加为好友。

我的问题是:

如何获取好友列表中所有 "user1" 值为 0 的用户好友列表的 ID?我可以在一次查询中完成吗?

我想我需要遍历所有好友列表和每个好友列表的 orderbykey 并寻找 "user1"。或者有什么好的方法可以做到这一点?

任何答案将不胜感激,谢谢!

如果您下次多介绍一下您已经尝试过的内容,将会有所帮助。或者至少指定 language/environment 您的目标。

但在 JavaScript 中,您可以获得那些用户:

var ref = new Firebase('https://yours.firebaseio.com/friendlist');
var query = ref.orderByChild('user1').equalTo(0);
query.once('value', function(usersSnapshot) {
    usersSnapshot.forEach(function(userSnapshot) {
        console.log(userSnapshot.key());
    });
});

使用您指定的示例数据,这将打印:

user2

您应该添加(并且会收到警告)索引以有效执行此查询:

{
  "rules": {
    "friendlist": {
      ".indexOn": ['user1']
    }
  }
}

如果没有这个索引,Firebase 客户端只会将所有数据下载到客户端并进行过滤 client-side。有了索引,就会进行查询server-side.

更好的数据模型

您可能想要搜索任何朋友,这会将索引变为:

      ".indexOn": ['user1', 'user2', 'user3']

但是使用这种结构,无论何时添加用户都需要添加索引。 Firebase SDK 没有 API 添加索引,这通常很好地表明您的数据结构不符合您的需求。

使用 NoSQL 数据库时,您的数据结构应满足您正在构建的应用程序的需要。由于您要查询 user1 的朋友,因此您也应该以该格式存储数据:

"friendlist" : {
    "user1" : {
        "user3" : 1
    },
    "user2" : {
        "user1" : 0
    }
    "user3" : {
        "user1" : 1
    }
},
"friendsOf": {
    "user1": {
      "user2": 0,
      "user3": 1
    },
    "user3": {
      "user1": 1
    }
}

如您所见,我们现在存储了两个列表: * friendList 是您的原始列表 * friendsOf 是原始列表的倒数

当您需要知道谁与用户 1 成为朋友时,您现在可以通过以下方式读取该数据:

ref.child('friendsOf').child('user1').on('value'...

请注意,我们不再需要对此进行查询,这使得操作在数据库端更具可扩展性。

原子更新

使用这种新的数据模型,添加好友关系时需要在两个地方写入数据。您可以使用两个 set()/update() 操作来完成此操作。但是在最近的 Firebase SDK 中,您还可以像这样在单个更新中执行这两种写入:

function setRelationship(user1, user2, value) {
    var updates = {};
    updates['friendList/'+user1+'/'+user2] = value;
    updates['friendsOf/'+user2+'/'+user1] = value;
    ref.update(updates);
}
setRelationship('user3', 'user4', 1);

以上将向 Firebase 服务器发送一条命令,以将关系写入 friendListfriendsOf 节点。