Я пытаюсь добавить идентификаторы в мою коллекцию пользователей для контроля доступа в Firestore, используя Angular Fire 2.

 grantCompanyAccess (user, companyId) {
    try {
      const userAccess: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
      return userAccess.set({companies: [companyId]});
    } catch (error) {
      console.log(error);
    }
  }

  removeCompanyAccess (user, companyId) {
    try {
      const userAccess: AngularFirestoreDocument<any> = this.afs.doc(`users/${user.uid}`);
      const userData = {
        companies:  [{companyId}]
      };
      // return userAccess.collection('companies').doc(companyId).delete();
      return userAccess.collection('companies').doc(companyId).delete();
    } catch (error) {
      console.log(error);
    }
  }

В настоящее время метод предоставления заменяет идентификатор в массиве. Как добавить в массив, если значение не существует ({merge: true} не работает), и удалить из массива методом remove.

1
Badger 29 17 Май 2019 в 11:28

2 ответа

Лучший ответ

Сначала вы должны получить массив из firebase, а затем вставить новый идентификатор в этот массив. После этого вы можете установить компании с обновленным массивом.

0
RobrechtVM 17 Май 2019 в 11:42

Я думаю, что ответ, помеченный как принятый, неверен. Я знаю, что OP спрашивает «в Angular Firestore», но предложенный ответ дает OP решение, которое навредит ему, и я считаю, что это не хорошо.

Если у вас есть более одного источника, который может обновлять данные (например, несколько пользователей приложения), вы рано или поздно потеряете данные. Принятый ответ не решает проблему параллелизма.

Представьте себе этот сценарий:

  1. Пользователь A выбирает данные и массив, который он хочет обновить, выглядит следующим образом: [1,2,3]

  2. Пользователь A теперь добавляет один элемент (4) -> [1,2,3,4] (еще не отправляет на сервер)

  3. Пользователь B теперь выбирает те же данные (массив выглядит так [1,2,3])

  4. Пользователь A теперь отправляет сообщения на сервер (новые данные находятся на сервере и выглядят так [1,2,3,4]

  5. Пользователь B помещает один элемент (5) в массив, который он имеет локально, и теперь он выглядит так [1,2,3,5]. Теперь он подталкивает к серверу.

  6. В результате данные на сервере перезаписываются, и сервер удерживает [1,2,3,5]

  7. В качестве эффекта (4) значение, которое Пользователь А выдвинул на шаге 2, теперь теряется из массива.

Фактическим решением для того, что вы хотите сделать, является использование Firestore Cloud Function, в рамках которой вы можете использовать метод ArrayUnion. Затем предоставьте эту функцию через HTTP или вызываемую конечную точку и затем используйте if из вашего приложения. Не делайте этого с помощью AngularFirestore, так как на данный момент он не обеспечивает достаточного решения.

Надеюсь, это поможет, ура

0
azrahel 11 Дек 2019 в 14:54