Firestore - 如何在将文档添加到集合后获取文档 ID

Posted

技术标签:

【中文标题】Firestore - 如何在将文档添加到集合后获取文档 ID【英文标题】:Firestore - How to get document id after adding a document to a collection 【发布时间】: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。您可以在添加文档之前生成密钥。 【参考方案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
              )

【讨论】:

以上是关于Firestore - 如何在将文档添加到集合后获取文档 ID的主要内容,如果未能解决你的问题,请参考以下文章

如何将子集合添加到 Firebase Cloud Firestore 中的文档

Firestore,检测添加到集合中的新文档等

如何将具有自定义 ID 的文档添加到 Firestore

如何在 Swift 上将具有自定义 ID 的文档添加到 Firebase (Firestore)

FLUTTER,FIRESTORE:我有一个流构建器,它从集合中的所有文档中返回某个字段..如何添加查询?

Cloud Functions:如何将 Firestore 集合复制到新文档?