You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

删除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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 19:30:34