Удаление объекта из массива в Firestore - PullRequest
0 голосов
/ 06 сентября 2018

Я только вхожу в Firebase и до сих пор копаю его, но у меня возникла небольшая проблема с использованием функции Cloud для удаления элемента из массива в коллекции. В приложении, которое я использую, у пользователей есть документ в коллекции пользователей, который содержит пользовательские данные, которые не вписываются в модель аутентификации. Данные выглядят так:

Снимок экрана структуры пользовательской коллекции.

(Это приложение для фитнеса, поэтому массив называется «тренировки»)

Пользователь имеет возможность создать тренировку, и когда он это делает, после ее создания облачная функция, отслеживающая новые тренировки, добавляет идентификатор вновь созданной тренировки в пользовательский документ, добавляя его в массив тренировок с помощью arrayUnion. :

exports.addWorkoutToAuthorsListOfWorkouts = functions.firestore
    .document('workouts/{workoutId}')
    .onCreate((snap, context) => {
      const id = context.params.workoutId
      const name = snap.data().title
      const uid = snap.data().author

      const workout_reference = { id: id, name: name, uid: uid }
      const workoutsRef = admin.firestore().collection("users").doc(uid)

      return workoutsRef.update({
        workouts: admin.firestore.FieldValue.arrayUnion(workout_reference)
      })
    })

Это работает нормально, но я хочу, чтобы пользователь мог удалять тренировки, и я не добавил строку в массив тренировок, а вместо этого объект, подобный этому:

{ id: "1214", name: "My workout", uid: "123asd" }

Теперь для этого точного варианта использования я мог бы удалить массив в своем приложении ReactJS, а затем выполнить обновление, но я собираюсь добавить возможность пользователям "нравится" тренировки других пользователей, что будет в результате ссылка на тренировку будет добавлена ​​к "тренировкам" в их личном пользовательском документе. Поэтому, если я, как создатель тренировки, удаляю свою тренировку, мне нужно иметь возможность удалить ее из массива тренировок любого пользователя, у которого она есть. Использование arrayRemove не сработало, потому что (я полагаю) я не смог передать объект, который нужно удалить.

Каков наилучший способ сделать это? Я сделал эту попытку:

exports.removeWorkoutFromAuthorsListOfWorkouts = functions.firestore
  .document('workouts/{workoutId}')
  .onDelete((snap, context) => {

    const id =  context.params.workoutId
    const uid = snap.data().author
    const name = snap.data().name
    let newWorkouts = new Array()

    admin.firestore().collection("users").doc(uid).collection("workouts").get().then((querySnapshot) => {
      querySnapshot.forEach((doc: any) => {
          if (doc.id !== id) {
            newWorkouts.push(doc.data())
          }
      });
    });

    const workoutsRef = admin.firestore().collection("users").doc(uid)

    return workoutsRef.update({
      workouts: newWorkouts
    })
  })

Но Firebase это совсем не понравилось, и я достаточно новичок в платформе, поэтому я понимаю, что это скорее всего из-за пробела в знаниях, а не из-за проблем с Firestore или Cloud Functions.

Буду очень признателен за любую помощь, которую вы сможете оказать. Ура!

ОБНОВЛЕНИЕ: Работает со следующим кодом:

exports.removeWorkoutFromSubscribersListOfWorkouts = functions.firestore
  .document('workouts/{workoutId}')
  .onDelete((snap, context) => {
    const workoutId =  context.params.workoutId
    const subscribers = snap.data().subscribers
    let newWorkouts = new Array()

    subscribers.forEach(subscriber => {
      let userRef = admin.firestore().collection("users").doc(subscriber)

      return userRef.get().then(doc => {
        return userRef.update({
          workouts: doc.data().workouts.filter(workout => workout.id !== workoutId)
        })
      })
    })
    .catch(() => {
      console.log("error")
    })
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...