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

IT技术 javascript firebase google-cloud-firestore
2021-01-16 22:43:20

我只是在探索新的 Firebase Firestore,它包含一种名为reference. 我不清楚这是做什么的。

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

在 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) });

希望这可以帮助

所以实际上它不像外键。对我来说,它基本上什么都不做——reference如果我们不能将它用作真正的外键那么拥有它又有什么意义呢?
2021-03-14 22:43:20
感谢分享!我认为 Get 部分的第一行有一个错字,应该是db.collection('products').get(). 您是否尝试过直接获取用户?我猜newItem.userRef.get()应该工作而不是db.collection("users").doc(newItem.userRef.id).get()
2021-03-18 22:43:20
所以的唯一好处referencestring是,你可以调用get()的直接参考。还不是很有用。希望他们添加一个选项来自动使用相应的对象填充引用!
2021-03-18 22:43:20
谢谢你的例子!但是,如果我们查询文档时没有“填充”类型的选项,那么存储引用类型有什么意义呢?如果有任何人知道的填充选项,请告诉我。
2021-03-31 22:43:20
首先谢谢你的例子。我希望他们为未来添加一个“填充:真实”。否则保存参考是没有意义的。可以通过简单地uid通过它保存和引用来完成相同的操作
2021-04-12 22:43:20

引用非常像外键。

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

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

与 SQL 数据库中的外键不同,引用对于在单个查询中执行连接没有用。您可以将它们用于依赖查找(看起来像连接),但要小心,因为每跳都会导致到服务器的另一次往返。

我找不到有关此的任何信息?这将改变我的整个数据库结构,我需要了解更多......
2021-03-18 22:43:20
我需要将所有引用类型更改为字符串,因为查询总是会因引用类型而失败。我真的找不到关于如何按引用类型查询的任何信息:(如果有人知道如何按引用类型查询,请告诉我...
2021-03-23 22:43:20
拜托,你能分享一下可能的用例吗?是否可以查询该参考中的字段?例如,我有一个friends收藏,列出了我所有的朋友 ( friends/myId)。然后,我在friends另一个文档 ( group/groupId)字段中引用了这个文档我想只显示我的朋友谁是该组中,做这样的事情:where('friends.myId', '==', true)
2021-03-24 22:43:20
顺便说一句,更新文档以包含添加引用类型的示例可能很有用
2021-04-05 22:43:20
你有一个关于如何使用引用查询的例子(最好是 swift )?现在,我可以通过将原始 uid 存储为字符串来实现,但这似乎不对。
2021-04-06 22:43:20

对于那些寻找通过引用查询的 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

根据#AskFirebase https://youtu.be/Elg2zDVIcLo?t=276 ,现在的主要用例是 Firebase 控制台 UI 中的链接

这仍然不起作用 - 至少我无法在用户界面中发现它:)
2021-03-16 22:43:20
为什么要为 Firebase 控制台 UI 中的链接的主要目的构建数据类型?
2021-03-18 22:43:20

很多答案都提到它只是对另一个文档的引用,但不返回该引用的数据,但我们可以使用它来单独获取数据。

这是一个如何在 firebaseJavaScript SDK 9, modular版本中使用它的示例

让我们假设您的 firestore 有一个名为的集合products,它包含以下文档。

{
  name: 'productName',
  size: 'medium',
  userRef: 'user/dfjalskerijfs'
}

在这里,用户可以引用users集合中的文档我们可以使用以下代码段来获取产品,然后从引用中检索用户。

import { collection, getDocs, getDoc, query, where } from "firebase/firestore";
import { db } from "./main"; // firestore db object

let productsWithUser = []
const querySnaphot = await getDocs(collection(db, 'products'));
querySnapshot.forEach(async (doc) => {
  let newItem = {id: doc.id, ...doc.data()};
  if(newItem.userRef) {
    let userData = await getDoc(newItem.userRef);
    if(userData.exists()) {
      newItem.userData = {userID: userData.id, ...userData.data()}
    }
    productwithUser.push(newItem);
  } else {
    productwithUser.push(newItem);
  }
});

这里collection, getDocs, getDoc, query, where是与 Firestore 相关的module,我们可以在需要时使用它来获取数据。我们使用products直接文档返回的用户引用来使用以下代码获取该引用的用户文档,

let userData = await getDoc(newItem.userRef);

要阅读有关如何使用module化版本 SDK 的更多信息,请参阅官方文档以了解更多信息。

请注意,尽管对 ref 的每个请求都将计入读取
2021-03-25 22:43:20