删除Firestore用户账号时,如何移除其ID在所有预订文档数组中?
问题描述
我的应用支持用户创建并跟踪简单预订,Firestore里的每个预订文档都有一个users数组,用来存储创建同一预订(相同名称、日期、场次)的用户ID。现在需要实现:删除用户账号时,自动把该用户ID从所有包含它的users数组中移除,同时保留其他用户ID。
现有代码如下:
const ProfileScreen = () => { const navigation = useNavigation(); const auth = getAuth(); const uid = auth.currentUser.uid; const docRef = doc(db, 'users', uid); const handleSignOut = () => { auth .signOut() .then(() => { navigation.navigate('Welcome') }) .catch(error => alert(error.message)) } const handleDeleteProfile =() => { const korisnikID = getAuth().currentUser.uid; const user = getAuth().currentUser; auth.signOut() .then(() => { navigation.navigate('Welcome'); // removing the user ID from the arrays deleteDoc(doc(db, "users", korisnikID)) .then(() => { deleteUser(user); }).catch((error) => { console.log(error); }); }); } const [user, setUser] = useState({}); useEffect(() => { const getUser = async () => { const snap = await getDoc(docRef) setUser({user, ...snap.data()}) } getUser() },[]) return ( <View style = {styles.container}> <View style = {styles.profileContainer}> <Image source={require('../assets/profile.jpeg')} style = {styles.image} /> <View style = {styles.profileInfo}> <Text style = {styles.name}>{user.name} ({user.age})</Text> <Text style = {styles.location}>{user.city}, {user.country}</Text> </View> </View> <View style = {styles.infoContainer}> <Text style = {styles.text1}>Username</Text> <View style = {styles.info}> <Text style = {styles.text2}>{user.username}</Text> </View> <Text style = {styles.text1}>Favorite movie:</Text> <View style = {styles.info}> <Text style = {styles.text2}>{user.movie}</Text> </View> <Text style = {styles.text1}>About me</Text> <View style = {styles.info}> <Text style = {styles.text2}>{user.bio}</Text> </View> </View> <View style = {styles.buttonContainer}> <TouchableOpacity onPress = {handleSignOut} style = {styles.button}> <Text style = {styles.buttonText}>Sign out</Text> </TouchableOpacity> </View> <View style = {styles.buttonContainer}> <TouchableOpacity onPress = {handleDeleteProfile} style = {styles.buttonDelete}> <Text style = {styles.buttonText}>Delete account</Text> </TouchableOpacity> </View> </View> ) } export default ProfileScreen
Firestore数据库结构:
- 用户文档:包含name、age、city、country、username、movie、bio等字段
- 预订文档:包含name(预订名称)、date(日期)、time(场次)、users(用户ID数组)字段
解决方案
要实现需求,需按以下步骤操作,将逻辑整合到删除账号的函数中:
具体实现代码
替换原有的handleDeleteProfile函数,加入清理预订数组的逻辑:
const handleDeleteProfile = async () => { const korisnikID = getAuth().currentUser.uid; const user = getAuth().currentUser; try { // 1. 查询所有包含当前用户ID的预订文档 const bookingsQuery = query(collection(db, 'bookings'), where('users', 'array-contains', korisnikID)); const bookingsSnapshot = await getDocs(bookingsQuery); // 2. 批量更新预订文档,移除数组中的用户ID const updateTasks = bookingsSnapshot.docs.map(doc => { return updateDoc(doc.ref, { users: arrayRemove(korisnikID) }); }); await Promise.all(updateTasks); // 3. 执行登出、删除用户文档、删除认证账号 await auth.signOut(); navigation.navigate('Welcome'); await deleteDoc(doc(db, "users", korisnikID)); await deleteUser(user); console.log("账号删除完成,已清理所有相关预订记录"); } catch (error) { console.error("删除账号时出错:", error); alert("账号删除失败,请稍后重试"); } }
关键说明
- 用
where('users', 'array-contains', korisnikID)精准筛选出所有包含该用户ID的预订文档 - 借助Firestore内置的
arrayRemove操作符,安全移除数组中指定的用户ID,不会干扰其他元素 - 用
Promise.all批量处理更新操作,提升执行效率 - 所有操作包裹在
try/catch中,统一处理错误,避免单步骤失败导致数据不一致
注意:需确保Firestore规则允许对bookings集合进行查询和更新操作,否则会出现权限错误。
内容的提问来源于stack exchange,提问作者Mihailo
相关产品推荐
相关产品推荐

