Обновление firestore с использованием предыдущего состояния

1

Можно ли обновить firestore, используя предыдущее состояние?

Так, например, у меня есть адресный документ, в котором есть поле users которое содержит массив пользователей, связанных с адресом. когда я хочу добавить нового пользователя в этот массив, мне нужен предыдущий массив, иначе я закончу переписывание текущих данных новыми данными.

Поэтому я получаю что-то вроде этого.

   firestore()
    .collection("addresses")
    .doc(addressId)
    .get()
    .then(doc => {
      this.db
        .collection("addresses")
        .doc(addressId)
        .update({
          users: [...doc.data().users, id]
        })
    });

Есть ли способ получить доступ к предыдущим данным без необходимости вложенных вызовов?

если не

Есть ли лучший способ управлять отношениями?

Теги:
firebase
google-cloud-firestore

1 ответ

1
Лучший ответ

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

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

var docRef = firestore()
    .collection("addresses")
    .doc(addressId);

return db.runTransaction(function(transaction) {
    // This code may get re-run multiple times if there are conflicts.
    return transaction.get(docRef).then(function(doc) {
        transaction.update(docRef, { users: [...doc.data().users, id ]});
    });
}).then(function() {
    console.log("Transaction successfully committed!");
}).catch(function(error) {
    console.log("Transaction failed: ", error);
});

Оптимальным решением является использование структуры данных, которая не требует, чтобы текущее значение добавляло новые значения. Это одна из причин, почему Firebase рекомендует не использовать массивы: они по своей сути трудно масштабировать, когда несколько пользователей могут добавлять элементы в массив. Если нет необходимости поддерживать порядок между пользователями, я бы рекомендовал использовать подобную структуру для пользователей:

users: {
  id1: true,
  id2: true
}

Это коллекция с двумя пользователями (id1 и id2). true значения - это только маркеры, поскольку у вас не может быть поля без значения.

С этой структурой добавление пользователя так же просто, как:

firestore()
    .collection("addresses")
    .doc(addressId)
    .update({ "users.id3": true })

Также см. Документацию Firestore по работе с массивами, списками и наборами

  • 0
    API транзакции был именно то, что я искал, спасибо! Я собираюсь принять второе решение и удалить массив, я думаю, что будет намного легче управлять. Спасибо, Фрэнк.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню