【问题标题】:Firestore - How to get document id after adding a document to a collectionFirestore - 如何在将文档添加到集合后获取文档 ID
【发布时间】:2018-07-22 06:23:21
【问题描述】:

有没有办法获取将文档添加到集合后生成的文档 ID?

如果我将一个文档添加到代表社交媒体应用中“帖子”的集合中,我想获取该文档 ID 并将其用作不同集合中另一个文档中的字段。

如果我无法获取添加文档后生成的文档 ID,我是否应该只计算一个随机字符串并在创建文档时提供该 ID?这样我可以使用与其他文档中的字段相同的字符串吗?

快速结构示例:

POST (collection)
    Document Id - randomly generated by firebase or by me
USER (collection)
    Document Id - randomly generated by firebase
       userPost: String (this will be the document id 
                         in the post collection that I'm trying to get)

【问题讨论】:

  • 检查这个answer。您可以在添加文档之前生成密钥。

标签: firebase google-cloud-firestore


【解决方案1】:

是的,这是可能的。当您对集合调用 .add 方法时,将返回一个 DocumentReference 对象。 DocumentReference 有id 字段,因此您可以在创建文档后获取id。

// Add a new document with a generated id.
db.collection("cities").add({
    name: "Tokyo",
    country: "Japan"
})
.then(function(docRef) {
    console.log("Document written with ID: ", docRef.id);
})
.catch(function(error) {
    console.error("Error adding document: ", error);
});

这个例子是用 JavaScript 编写的。如需其他语言,请访问documentation

【讨论】:

    【解决方案2】:

    如果使用 Promise,我建议使用粗箭头函数,因为它打开了使用 this.foo 的可能性,即使在 .then 函数中也是如此

        db.collection("cities").add({
            name: "Tokyo",
            country: "Japan"
        })
        .then(docRef => {
            console.log("Document written with ID: ", docRef.id);
            console.log("You can now also access this. as expected: ", this.foo)
        })
        .catch(error => console.error("Error adding document: ", error))
    

    使用function(docRef)表示无法访问this.foo,会报错

        .then(function(docRef) {
            console.log("Document written with ID: ", docRef.id);
            console.log("You can now NOT access this. as expected: ", this.foo)
        })
    

    虽然粗箭头功能将允许您按预期访问this.foo

        .then(docRef => {
            console.log("Document written with ID: ", docRef.id);
            console.log("You can now also access this. as expected: ", this.foo)
        })
    

    编辑/添加 2020:

    如今,一种更流行的方式可能是使用 async/await 代替。请注意,您必须在函数声明前添加async

        async function addCity(newCity) {
          const newCityAdded = await db.collection("cities").add(newCity)
          console.log("the new city:", newCityAdded)
          console.log("it's id:", newCityAdded.id)
        }
    

    如果您只想要 id,可以使用解构来获取它。解构允许您在响应中获取任何键/值对:

        async function addCity(newCity) {
          const { id } = await db.collection("cities").add(newCity)
          console.log("the new city's id:", id)
        }
    

    也可以使用解构来获取值并重命名为您想要的任何内容:

        async function addCity(newCity) {
          const { id: newCityId } = await db.collection("cities").add(newCity)
          console.log("the new city's id:", newCityId)
        }
    

    【讨论】:

    • 谢谢!这很有帮助。我能够获得文档 ID。然后我想获取这个 ID,将用户发送到一个动态生成的新 URL,该 ID 构成 URL 的一部分,并显示来自 firebase firestore 的该特定文档的数据。欢迎任何想法/帮助。
    • 您可以为此使用模板文字:window.location.href = `https://mypage.com/${id}` 。请注意,url 周围不是'",而是使使用此方法成为可能的反引号。另一种方法是创建一个带有 id 的新字符串,类似于:const newUrl = "https://mypage.com" + id,然后是window.location.href = newUrl。如果您之前没有使用过模板文字,请查看 (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…),使用它非常棒:)
    【解决方案3】:

    如果你想使用async/await而不是.then(),你可以这样写:

    const post = async (doc) => {
        const doc_ref = await db.collection(my_collection).add(doc)
        return doc_ref.id
    }
    

    如果你想捕捉这个函数中的任何错误,包括.catch()

        const doc_ref = await db.collection(my_collection).add(doc).catch(err => { ... })
    

    或者你可以让调用函数捕获错误。

    【讨论】:

      【解决方案4】:

      这就是我所做的,正如您在问题中提到的那样。不确定这是否是最佳做法,但它可以轻松访问。

      首先创建文档时

      firebase.firestore().collection("cities").doc().set({ name: Tokyo,
      country: Japan })
      

      您可以设置文档的 id 并将该确切的 id 作为属性放入其中:

      firebase.firestore().collection("cities").doc('id-generated-from-somewhere')
      .set({ id: 'id-generated-from-somewhere', name: Tokyo, country: Japan })
      

      【讨论】:

      • 这对你来说实在是太多了。您最终可能会生成一个已经存在的 ID,这会损坏您的数据。
      【解决方案5】:

      正如其他人也提到的,我们可以在添加后获取文档参考。 代表id获取到文档引用后,我们可以更新同样的

      Service.ts 文件

      async funName(data: Data){
            let docRef = this.firestore.collection('table-name').add(data);
            console.log(docRef)
            try {
              const docAdded = await docRef;
              console.log(docAdded.id);
              this.firestore.doc('table-name/' + docAdded.id).update({ id: docAdded.id });
              return docRef;
            }
            catch (err) {
              return err;
            }
          }
      

      component.ts 文件

      async addData(){
          try{
            let res =  await this.dataServ.funName(this.form.value);
            this.snackbar.open('success', 'Success');
          }catch(ex){
            this.disabled = false;
            this.snackbar.open('err', 'Error')
            console.log(ex, 'exception');
          }
        }
      

      【讨论】:

        【解决方案6】:

        对于 Android、Java,您应该先获取文档 ID,然后再将 set()add() 某些内容发送到 Firestore。像这样:

            //Fields: 
            CollectionReference toolsCollectionRef = FirebaseFirestore.getInstance().collection(toolsCollection);
            CustomPOJO_Model toolToPost; 
            
            //In Methods: 
            String newDocID= toolsCollectionRef.document().getId();   //Get Doc ID first. 
            toolToPost.setToolID(newDocID);
            
            //Now use the doc ID:
            toolsCollectionRef.document(newDocID).set(toolToPost.getConvertedTool_KeyValuePair ()).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                }
            });
            
            //Re-use same ID in another post: 
            usersCollectionRef.document(mAuth.getUid()).collection(usersToolsCollection).document(toolToPost.getToolID()).set(toolToPost.getConvertedTool_KeyValuePair()); 
        

        【讨论】:

          【解决方案7】:

          对于 FB Firestore 版本 9 (JS/Web),使用以下语法:

          import { addDoc, doc, Timestamp, updateDoc } from "firebase/firestore";
          
              //add document to 'posts' collection with auto id
                  const newItem = await addDoc(collection(db, 'posts'), {
                            caption: post.value.caption || "No caption provided",
                            location: post.value.location || "No location provided",
                            imageUrl: imageUrl.value,
                            createdAt: Timestamp.now(), 
                      });
                          
              //get new document id an update it to the file as id field.
              const fileID = newItem.id
                          console.log('added file:', fileID);
                          const updateDocId = doc(db, "posts", fileID) ;
                          await updateDoc(updateDocId, {
                            id: fileID
                        })
          

          【讨论】:

            猜你喜欢
            • 2020-12-04
            • 2020-01-05
            • 1970-01-01
            • 2019-09-24
            • 2018-12-05
            • 1970-01-01
            • 1970-01-01
            • 2020-01-12
            • 1970-01-01
            相关资源
            最近更新 更多