62 votes

Comment créer/mettre à jour plusieurs documents à la fois dans Firestore ?

Est-il possible de stocker plusieurs documents dans Firestore avec une seule requête ? Avec cette boucle, c'est possible mais cela entraînerait une opération de sauvegarde par élément de la liste.

for (counter in counters) {
    val counterDocRef = FirebaseFirestore.getInstance()
            .document("users/${auth.currentUser!!.uid}/lists/${listId}/counters/${counter.id}")
    val counterData = mapOf(
            "name" to counter.name,
            "score" to counter.score,
    )
    counterDocRef.set(counterData)
}

92voto

Yassin Points 580

Extrait de la documentation de Firebase :

Vous pouvez également exécuter plusieurs opérations en un seul lot, avec toute combinaison des méthodes set(), update() ou delete(). Vous pouvez effectuer des écritures par lots sur plusieurs documents, et toutes les opérations du lot se terminent de manière atomique.

// Get a new write batch
WriteBatch batch = db.batch();

// Set the value of 'NYC'
DocumentReference nycRef = db.collection("cities").document("NYC");
batch.set(nycRef, new City());

// Update the population of 'SF'
DocumentReference sfRef = db.collection("cities").document("SF");
batch.update(sfRef, "population", 1000000L);

// Delete the city 'LA'
DocumentReference laRef = db.collection("cities").document("LA");
batch.delete(laRef);

// Commit the batch
batch.commit().addOnCompleteListener(new OnCompleteListener<Void>() {
    @Override
    public void onComplete(@NonNull Task<Void> task) {
        // ...
    }
});

Opérations d'écriture multiples de Firestore

J'espère que ça aidera

0 votes

Oui, c'est exactement ce que je cherchais et que j'ai malheureusement manqué dans la documentation.

1 votes

Existe-t-il un moyen de lire en masse, similaire à cette capacité d'écrire, c'est-à-dire que si j'ai 10 références de documents, puis-je les obtenir en masse ? Merci !

1 votes

@MarcelBochtler Il n'est pas mentionné dans la documentation qu'une opération par lot est facturée comme une lecture unique. Le batching est un moyen d'effectuer des opérations de manière atomique (toutes en même temps ou pas du tout), mais c'est différent de la facturation. La page de facturation que je cite dans ma réponse indique clairement que "Vous êtes facturé pour chaque lecture, écriture et suppression de document que vous effectuez avec Cloud Firestore."

9voto

javahaxxor Points 54

Mettre à jour certaines propriétés sur tous les documents d'une collection :

resetScore(): Promise<void> {
  return this.usersCollectionRef.ref.get().then(resp => {
    console.log(resp.docs)
    let batch = this.afs.firestore.batch();

    resp.docs.forEach(userDocRef => {
      batch.update(userDocRef.ref, {'score': 0, 'leadsWithSalesWin': 0, 'leadsReported': 0});
    })
    batch.commit().catch(err => console.error(err));
  }).catch(error => console.error(error))
}

2voto

Rashid Iqbal Points 8
void createServiceGroups() {
        List<String> serviceGroups = [];

        serviceGroups.addAll([
          'Select your Service Group',
          'Cleaning, Laundry & Maid Services',
          'Movers / Relocators',
          'Electronics & Gadget',
          'Home Improvement & Maintenance',
          'Beauty, Wellness & Nutrition',
          'Weddings',
          'Food & Beverage',
          'Style & Apparel',
          'Events & Entertainment',
          'Photographer & Videographers',
          'Health & Fitness',
          'Car Repairs & Maintenance',
          'Professional & Business Services',
          'Language Lessons',
          'Professional & Hobby Lessons',
          'Academic Lessons',
        ]);
        Firestore db = Firestore.instance;
        // DocumentReference ref = db
        //     .collection("service_groups")
        //     .document(Random().nextInt(10000).toString());

        // print(ref.documentID);

        // Get a new write batch

        for (var serviceGroup in serviceGroups) {
          createDocument(db, "name", serviceGroup);
        }

        print("length ${serviceGroups.length}");
      }

      createDocument(Firestore db, String k, String v) {
        WriteBatch batch = db.batch();
        batch.setData(db.collection("service_groups").document(), {k: v});
        batch.commit();
      }

   createDocument(Firestore db, String k, String v) {
            WriteBatch batch = db.batch();
            batch.setData(db.collection("service_groups").document(), {k: v});
            batch.commit();
          }

Cela peut vous aider :

 for (var serviceGroup in serviceGroups) {
      createDocument(db,  "name", serviceGroup  );
    }

1voto

Thamizharasu Points 96

Si vous avez besoin d'utiliser add() au lieu de set, veuillez suivre le code ci-dessous,

public void createMany(List<T> datas) throws CustomException {
    Firestore firestore = connection.firestore();
    CollectionReference colRef = firestore.collection("groups");

    WriteBatch batch = firestore.batch();
    for (T data : datas) {
        batch.create(colRef.document(), data);
    }

    ApiFuture<List<WriteResult>> futureList = batch.commit();
    try {
        for (WriteResult result : futureList.get()) {
            logger.debug("Batch output: {}", result.getUpdateTime());
        }
    } catch (InterruptedException | ExecutionException e) {
        throw new CustomException(500, e.getMessage());
    }
}

Cela peut être utile lorsque vous avez besoin de générer l'identifiant à partir de la base de données firestore.

0 votes

batch.create(...) n'est pas disponible. Regardez stackoverflow.com/a/46739496/8468233 pour voir comment la création par lots est effectuée

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X