到目前为止,我只是进入Firebase,并进行了深入研究,但是使用Cloud Function从集合中的数组中删除项目时遇到了一个问题。在我使用的应用程序中,用户在用户集合中有一个文档,其中包含身份验证模型中不适合的用户特定数据。数据如下:
Screenshot of user collection structure.
(这是与健身相关的应用,因此该数组称为“锻炼”)
用户具有创建锻炼的能力,创建锻炼后,云功能可监视新锻炼,并将新创建锻炼的ID添加到用户文档中,并使用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")
})
})