Добавление документа Firestore как часть обновления документа - PullRequest
0 голосов
/ 10 апреля 2019

Я хочу иметь возможность создавать новый документ в одной коллекции как часть обновления документа в другой.

Простая версия. Пользователь обновляет статус задачи, нажимая кнопку.

Что мне нужно, это

completeTask(task:ITask) : Promise<any>
{
  const userId = this.auth.userId;

  this.afs.collection('Tasks').doc(task.id).update({Status: 'COMPLETE'});
  this.afs.collection('Notifications').add({Task:task.id, Status: 'COMPLETE', UserId: userId});
  // ...
  // return Promise here;
}

Вышеуказанное должно происходить как часть одной операции. Я прочитал все, что я могу найти как в пакетном режиме, так и в транзакциях, но не могу найти, как это сделать правильно. Я могу просто запустить их последовательно и вернуть

Promise.all(taskPromise, notifyPromise);

или зацепите одно от другого - но я надеялся на более элегантное решение.

Ответы [ 2 ]

0 голосов
/ 13 апреля 2019

Я нашел ответ, который искал.Проблема с созданием документа как части пакета заключается в том, что вам нужно сгенерировать свой собственный ключ - либо используя тот, которым вы управляете, либо получая его из Firestore.Оглядываясь назад, это очевидно, поскольку пакет должен работать с данным документом - меня отвлек тот факт, что .add () при обычной ссылке добавит ваш новый документ и даст ему Id - я искал способсделать это с помощью пакета.

Вот код, который я в конечном итоге использовал

@Injectable({
  providedIn: 'root'
})
export class ProjectService {
  // AuthService is implied but not shown as part of this example
  constructor(private afs: AngularFirestore, private auth:AuthService) { }

  // Update Project and write an event log to the projects ActivityLog
  // as part of the same write
  UpdateProject(projectName: string, data:any) : Promise<void>
  {
    // Get a batch reference
    const batch = this.afs.firestore.batch();

    // Reference to the Project document that needs to be updated
    const ref = this.afs.collection('Projects').doc(projectName);

    // Get a unique Firestore ID for the ActivityLog document
    const newLogId = this.afs.createId();

    // Reference to the ActivityLog doc using the ref and ID created above
    const logref = ref.collection('ActivityLog').doc(newLogId);
    batch.update(ref.ref, data);

    // Create the new entry
    batch.set(logref.ref, {
      Created: firestore.FieldValue.serverTimestamp(), 
      User: this.auth.UserName,
      Action: 'Update', 
      Data: JSON.stringify(data)
    });

    return batch.commit();
  }
}

В моем компоненте

onUpdate(data:any) {
  this.projectSvc.UpdateProject(this.projectName, data)
    .then(() => alert('Update successful'));
}

Бит ключа генерировал Id ииспользуя это в ссылке на новый документ ActivityLog (в данном случае).

Боковая панель: Это могло бы быть сделано как функция облака - причина, по которой мы даже смотрим на это, заключается в том, что нам нужно знатьПользователь, который внес изменение и на основании проведенного исследования вы не можете получить идентификатор пользователя, который вызвал изменение в Firestore (вы можете в Realtime, я полагаю).

0 голосов
/ 10 апреля 2019

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...