Firebase Firestore“参考”数据类型有什么用处?


188

我只是在探索新的Firebase Firestore,它包含一个名为的数据类型reference。我不清楚这是做什么的。

  • 像外键吗?
  • 可以用来指向其他地方的集合吗?
  • 如果reference是实际参考,可以将其用于查询吗?例如,我是否可以有一个直接指向用户的引用,而不是将userId存储在文本字段中?我可以使用该用户参考进行查询吗?

17
我认为Firebase团队提供的这段视频可以为您详细介绍:youtube.com/watch?v=Elg2zDVIcLo(观看时间为4:36)
Adarsh

Answers:


89

引用非常类似于外键。

当前发布的SDK无法存储对其他项目的引用。在项目中,引用可以指向任何其他集合中的任何其他文档。

您可以像其他任何值一样在查询中使用引用:进行过滤,排序和分页(startAt / startAfter)。

与SQL数据库中的外键不同,引用对于在单个查询中执行联接没有用。您可以将它们用于相关查找(看起来像join),但是要小心,因为每个跃点都会导致服务器再次往返。


9
请,您可以分享可能的用例吗?是否可以查询该引用中的字段?例如,我有一个friends列出所有朋友的收藏集(friends/myId)。然后,在friends另一个文档(group/groupId)的字段中引用此文档。我只想显示该组中的我的朋友,做这样的事情:where('friends.myId', '==', true)
威尔

107
顺便说一句,更新文档以包含添加引用类型的示例可能会很有用。
威尔

11
我找不到有关此的任何信息?这将改变我的整个数据库结构,我需要了解更多...
Ruben

3
您是否有一个使用引用查询的示例(最好是快捷方式)?现在,我可以通过将原始uid存储为字符串来做到这一点,但这似乎并不正确。
米奇·昌

6
我需要将我所有的引用类型都更改为字符串,因为查询始终会因引用类型而失败。我从字面上找不到任何有关如何通过引用类型进行查询的方法:(如果有人发现了如何通过引用类型进行查询的方法,请告诉我...
Sam Trent

131

在下面使用Firestore中的引用对我有用的内容进行添加。

正如其他答案所说,它就像一个外键。但是reference属性不会返回参考文档的数据。例如,我有一个产品列表,其中有一个userRef参考作为产品上的属性之一。获取产品列表,可以为我提供创建该产品的用户的参考。但这并没有为我提供该参考资料中的用户详细信息。我已经将其他后端用作带有指针的服务,在此之前,该指针具有“ populate:true”标志,该标志向后提供用户详细信息,而不仅仅是用户的参考ID,这在这里非常有用(希望将来有所改进) )。

下面是一些示例代码,我用于设置参考以及获取产品集合列表,然后从给定的用户参考ID获取用户详细信息。

在集合上设置参考:

let data = {
  name: 'productName',
  size: 'medium',
  userRef: db.doc('users/' + firebase.auth().currentUser.uid)
};
db.collection('products').add(data);

获取一个集合(产品)和每个文档上的所有参考(用户详细信息):

db.collection('products').get()
    .then(res => {
      vm.mainListItems = [];
      res.forEach(doc => {
        let newItem = doc.data();
        newItem.id = doc.id;
        if (newItem.userRef) {
          newItem.userRef.get()
          .then(res => { 
            newItem.userData = res.data() 
            vm.mainListItems.push(newItem);
          })
          .catch(err => console.error(err));
        } else {
          vm.mainListItems.push(newItem);  
        }

      });
    })
    .catch(err => { console.error(err) });

希望这可以帮助


3
感谢分享!我认为Get part的第一行中有一个错字,应该是db.collection('products').get()。您是否尝试过直接吸引用户?我想newItem.userRef.get()应该代替db.collection("users").doc(newItem.userRef.id).get()
Sergey Nefedyev '17

52
首先感谢您的示例。我希望他们为将来添加一个“填充:真实”。否则,保存引用将毫无意义。只需通过保存uid和引用,就可以完成相同的操作。
尔根·布兰德斯特(JürgenBrandstetter),

4
谢谢你的例子!但是,如果在查询文档时没有“填充”类型的选项,那么存储引用类型的意义何在?如果有任何人都知道的填充选项,请告诉我。
Harshil Shah

18
因此,实际上它不像外键。对我来说,它基本上什么都不做- reference如果我们不能将其用作真正的外键,那有什么意义呢?
Jean d'arme

14
因此,a reference优于a 的唯一优势string是,您可以get()直接调用引用。还不是很有用。希望他们添加一个选项,以使用相应的对象自动填充引用!
morgler

16

对于那些希望通过引用进行查询的Javascript解决方案的人-概念是,您需要在查询语句中使用“文档引用”对象

teamDbRef = db.collection('teams').doc('CnbasS9cZQ2SfvGY2r3b'); /* CnbasS9cZQ2SfvGY2r3b being the collection ID */
//
//
db.collection("squad").where('team', '==', teamDbRef).get().then((querySnapshot) => {
  //
}).catch(function(error) {
  //
});

(对这里的答案表示敬意:https : //stackoverflow.com/a/53141199/1487867

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.