Actualizar de manera condicional un documento de Firestore en una transacción

Actualizar de manera condicional un documento de Firestore en una transacción

Páginas de documentación que incluyen esta muestra de código

Para ver la muestra de código usada en contexto, consulta la siguiente documentación:

Muestra de código

Go

ref := client.Collection("cities").Doc("SF")
err := client.RunTransaction(ctx, func(ctx context.Context, tx *firestore.Transaction) error {
	doc, err := tx.Get(ref)
	if err != nil {
		return err
	}
	pop, err := doc.DataAt("population")
	if err != nil {
		return err
	}
	newpop := pop.(int64) + 1
	if newpop <= 1000000 {
		return tx.Set(ref, map[string]interface{}{
			"population": pop.(int64) + 1,
		}, firestore.MergeAll)
	}
	return errors.New("population is too big")
})
if err != nil {
	// Handle any errors in an appropriate way, such as returning them.
	log.Printf("An error has occurred: %s", err)
}

Java

final DocumentReference docRef = db.collection("cities").document("SF");
ApiFuture<String> futureTransaction = db.runTransaction(transaction -> {
  DocumentSnapshot snapshot = transaction.get(docRef).get();
  Long newPopulation = snapshot.getLong("population") + 1;
  // conditionally update based on current population
  if (newPopulation <= 1000000L) {
    transaction.update(docRef, "population", newPopulation);
    return "Population increased to " + newPopulation;
  } else {
    throw new Exception("Sorry! Population is too big.");
  }
});
// Print information retrieved from transaction
System.out.println(futureTransaction.get());

Node.js

const cityRef = db.collection('cities').doc('SF');
try {
  const res = await db.runTransaction(async t => {
    const doc = await t.get(cityRef);
    const newPopulation = doc.data().population + 1;
    if (newPopulation <= 1000000) {
      await t.update(cityRef, { population: newPopulation });
      return `Population increased to ${newPopulation}`;
    } else {
      throw 'Sorry! Population is too big.';
    }
  });
  console.log('Transaction success', res);
} catch (e) {
  console.log('Transaction failure:', e);
}

PHP

$cityRef = $db->collection('samples/php/cities')->document('SF');
$transactionResult = $db->runTransaction(function (Transaction $transaction) use ($cityRef) {
    $snapshot = $transaction->snapshot($cityRef);
    $newPopulation = $snapshot['population'] + 1;
    if ($newPopulation <= 1000000) {
        $transaction->update($cityRef, [
            ['path' => 'population', 'value' => $newPopulation]
        ]);
        return true;
    } else {
        return false;
    }
});

if ($transactionResult) {
    printf('Population updated successfully.' . PHP_EOL);
} else {
    printf('Sorry! Population is too big.' . PHP_EOL);
}

Python

transaction = db.transaction()
city_ref = db.collection(u'cities').document(u'SF')

@firestore.transactional
def update_in_transaction(transaction, city_ref):
    snapshot = city_ref.get(transaction=transaction)
    new_population = snapshot.get(u'population') + 1

    if new_population < 1000000:
        transaction.update(city_ref, {
            u'population': new_population
        })
        return True
    else:
        return False

result = update_in_transaction(transaction, city_ref)
if result:
    print(u'Population updated')
else:
    print(u'Sorry! Population is too big.')

Ruby

city_ref = firestore.doc "#{collection_path}/SF"

updated = firestore.transaction do |tx|
  new_population = tx.get(city_ref).data[:population] + 1
  if new_population < 1_000_000
    tx.update city_ref, { population: new_population }
    true
  end
end

if updated
  puts "Population updated!"
else
  puts "Sorry! Population is too big."
end

¿Qué sigue?

Para buscar y filtrar muestras de código para otros productos de Google Cloud, consulta el navegador de muestra de Google Cloud.