如何在Firebase Cloud Firestore中向文档添加子集合

rgo*_*alv 19 java android ios firebase google-cloud-firestore

该文档没有关于如何向文档添加子集合的任何示例.我知道如何将文档添加到集合以及如何将数据添加到文档,但是如何向文档添加集合(子集合)?

不应该有这样的方法:

dbRef.document("example").addCollection("subCollection")
Run Code Online (Sandbox Code Playgroud)

Ale*_*amo 16

假设我们有一个聊天应用程序,其数据库结构与此类似:

在此输入图像描述

subCollection在文档中编写,请使用以下代码:

DocumentReference messageRef = db
    .collection("rooms").document("roomA")
    .collection("messages").document("message1");
Run Code Online (Sandbox Code Playgroud)

如果你想创建messages集合并调用addDocument()1000次肯定会很昂贵,但这就是Firestore的工作原理.如果需要,您可以切换到Firebase实时数据库,其中写入次数无关紧要.但是关于Firestore中的支持数据类型,事实上你可以使用数组,因为它是suppoerted.在Firebase实时数据库中,您也可以使用array,但这是一种反模式.Firebase建议不要使用数组的原因之一是它使安全规则无法编写.

Cloud Firestore可以存储数组,它不支持查询数组成员或更新单个数组元素.但是,您仍然可以通过利用Cloud Firestore的其他功能对此类数据进行建模.这里的文档非常好解释.

您也无法创建包含1000条消息的子集合,并将所有消息添加到数据库中,同时考虑单个记录.它将被视为每个消息的一个写操作.总共1000次操作.上面的图片没有显示如何检索数据,它显示了一个数据库结构,其中你有这样的东西:

collection -> document -> subCollection -> document
Run Code Online (Sandbox Code Playgroud)


Gen*_* Bo 9

这是一个变体,其中子集合在集合级别存储 ID 值,而不是在子集合是包含附加数据的字段的文档中。

这对于连接1 对多 ID 映射非常有用,而不必钻取额外的文档:

function fireAddStudentToClassroom(studentUserId, classroomId) {

    var db = firebase.firestore();
    var studentsClassroomRef =
        db.collection('student_class').doc(classroomId)
          .collection('students');

    studentsClassroomRef
        .doc(studentUserId)
        .set({})
        .then(function () {
            console.log('Document Added ');
        })
        .catch(function (error) {
            console.error('Error adding document: ', error);
        });
}
Run Code Online (Sandbox Code Playgroud)

感谢@Alex 的回答

这个答案与这里的原始问题有点不同,它明确要求将集合添加到文档中。然而,在为这种情况寻找解决方案后,在文档或 SO 中没有找到任何提及,这篇文章似乎是分享研究结果的合理场所


Tho*_*hoe 5

这是我的代码:

firebase.firestore().collection($scope.longLanguage + 'Words').doc($scope.word).set(wordData)
  .then(function() {
    console.log("Collection added to Firestore!");
    var promises = [];
    promises.push(firebase.firestore().collection($scope.longLanguage + 'Words').doc($scope.word).collection('AudioSources').doc($scope.accentDialect).set(accentDialectObject));
    promises.push(firebase.firestore().collection($scope.longLanguage + 'Words').doc($scope.word).collection('FunFacts').doc($scope.longLanguage).set(funFactObject));
    promises.push(firebase.firestore().collection($scope.longLanguage + 'Words').doc($scope.word).collection('Translations').doc($scope.translationLongLanguage).set(translationObject));
    Promise.all(promises).then(function() {
      console.log("All subcollections were added!");
    })
    .catch(function(error){
      console.log("Error adding subcollections to Firestore: " + error);
    });
  })
  .catch(function(error){
    console.log("Error adding document to Firestore: " + error);
  });
Run Code Online (Sandbox Code Playgroud)

这将创建一个EnglishWords包含文档的集合of。该文档of包含三个子集:(AudioSources美国和英国口音的单词录音)FunFacts、 和Translations。子集合Translations有一个文档:Spanish. 该Spanish文档具有三个键值对,告诉您“de”是“of”的西班牙语翻译。

代码的第一行创建了集合EnglishWords。我们等待 Promise 解决.then,然后我们创建三个子集合。Promise.all告诉我们何时设置所有三个子集合。

恕我直言,当整个数组一起上传和下载时,我在 Firestore 中使用数组,即,我不需要访问单个元素。例如,单词 'of' 的字母数组将是['o', 'f']. 用户可以问,“我如何拼写‘of’?” 用户不会问,“'of' 中的第二个字母是什么?”

当我需要访问单个元素(也就是文档)时,我会使用集合。使用较旧的 Firebase 实时数据库,我必须下载数组,然后遍历数组forEach以获取我想要的元素。这是大量代码,并且具有深层数据结构和/或大型数组,我正在下载大量不需要的数据,并减慢我的应用程序forEach在大型数组上运行循环的速度。Firestore 将迭代器放在数据库的最后,这样我就可以请求一个元素,它只向我发送那个元素,从而节省了我的带宽并使我的应用程序运行得更快。如果您的计算机有宽带连接,这对于网络应用程序可能无关紧要,但对于数据连接较差且设备速度较慢的移动应用程序,这很重要。

这是我的 Firestore 的两张照片: 在此处输入图片说明

在此处输入图片说明