Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Firestore - Как получить идентификатор документа после добавления документа в коллекцию

Автор вопроса: BrejuroОтветов: 6

Есть ли способ получить идентификатор документа, который был сгенерирован после добавления документа в коллекцию?

Если я добавляю в коллекцию документ, представляющий "публикацию" в приложении социальной сети, я хочу получить этот идентификатор документа и использовать его как поле в другом документе в другой коллекции.

Если я не могу получить идентификатор документа, который был сгенерирован после добавления документа, должен ли я просто вычислить случайную строку и вместо этого указать идентификатор при создании документа? Таким образом, я могу использовать ту же строку, что и поле в другом моем документе?

Пример быстрой структуры:

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)
  • проверьте этот ответ. вы можете сгенерировать ключ перед добавлением документа. Hareesh 12.02.2018

firebasegoogle-cloud-firestore

Ответы

Ответ 1 · рейтинг 66 · Daniel Konovalenko

Да, это возможно. Когда вы вызываете метод .add для коллекции, возвращается объект DocumentReference. DocumentReference имеет поле 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. Посетите документацию для других языков.

Ответ 2 · рейтинг 33 · Christoffer

При использовании обещаний я бы рекомендовал использовать функцию жирной стрелки, поскольку она открывает возможность использования 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)
    }

И если вам нужен только идентификатор, его можно получить с помощью деструктуризации. Деструктуризация позволяет получить любую пару ключ / значение в ответе:

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

Ответ 3 · рейтинг 11 · Brent Washburne

Если вы хотите использовать 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 · рейтинг 3 · Gene

Для Android, Java вы должны получить идентификатор документа, прежде чем 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());

Ответ 5 · рейтинг 2 · VIKAS KOHLI

Как уже упоминалось другими, мы можем получить ссылку на документ после его добавления. После того, как мы получим ссылку на документ от имени 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 · рейтинг -2 · Stephen Hartfield

Вот что я делаю, как указано в вашем вопросе. Не уверен, что это лучшая практика, но она работает для легкого доступа.

При создании документа в первую очередь

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

вы можете установить идентификатор документа и указать этот точный идентификатор в качестве свойства:

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы