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

React Native集成Firebase更新用户资料时无文档可更新错误解决

React Native + Firebase 更新用户资料报错:No document to update

问题描述

错误信息:Unhandled promise rejection: FirebaseError: No document to update: projects/donate-83e96/databases/(default)/documents/

触发场景:登录后进入用户资料页面填写信息,点击「更新」按钮时出现该错误。Firestore免费试用到期前功能正常,到期后出现此问题。

用户提供的代码:

import {db,auth} from '../../firebase'

const EditProfile=({navigation})=>{

  const [image, setImage] = useState(null);
  const [uploading,setUploading] = useState(false)
  const [userData, setUserData] = useState(null);

  {/*retrieve data from firestore*/}

   React.useEffect(()=>{
    const getUserData = async()=>{

      db.collection("users")
      .doc(auth.currentUser?.uid)
      .get()
      .then(snap => {
          setUserData(snap.data());
      });
    }
    getUserData();
  },[])

 const updateProfile = async()=>{
    let imgUrl = await uploadImage();
    if(imgUrl == null && userData.userImg){
     imgUrl = userData.userImg
    }

    db.collection("users")
    .doc(auth.currentUser.uid)
    .update({
      name: userData.name,
      email: userData.email,
      phone: userData.phone,
      address: userData.address,
      userImg:userData.imgUrl
      
  })
  }


  {/*upload Image to firebase sotrage*/}

   const uploadImage = async ()=>{
      if(image == null){
        return "";
      }
      const blob = await new Promise((resolve, reject)=>{
        const xhr = new XMLHttpRequest();
        xhr.onload = function (){
           resolve(xhr.response)
        };
        xhr.onerror = function (){
            reject( new TypeError("Network request failed"))

        };
        xhr.responseType = "blob"
        xhr.open("GET",image,true)
        xhr.send(null)
      });
      const ref = firebase.storage().ref().child("images/" + new Date().toISOString())
      const snapshot = ref.put(blob)

      snapshot.on(
        firebase.storage.TaskEvent.STATE_CHANGED,
        ()=>{
            setUploading(true)
        },
        (error)=>{
            setUploading(false)
            console.log(error)
            blob.close();
            return ;
        },
        ()=>{
            snapshot.snapshot.ref.getDownloadURL().then((url)=>{
              
              setUserData({...userData, imgUrl: url})
              setUploading(false);
               // Alert.alert('Profile Updated', 'You profile Updated Successfully..!')
                console.log('donwload:', url)
                blob.close()
                return null
            })
        }
      )
     }

    function renderDetails(){
     return(
        <View>
            {/*edit name*/}
          <View>
          <TextInput 
             placeholder="Name"
             placeholderTextColor='#66666666'
             autoCorrect={false}
             value={userData ? userData.name : ''}
             onChangeText={(txt) => setUserData({...userData, name: txt})}
             style={{
                paddingLeft:5,
                color:'#05375a'
             }}
        />

       </View>   

            {/*edit email*/}  
            <View>
              <TextInput 
                  placeholder="Email"
                  placeholderTextColor='#66666666'
                  keyboardType="email-address"
                  autoCorrect={false}
                  value={userData ? userData.email : ''}
                  onChangeText={(txt) => setUserData({...userData, email: txt})}
                 style={{
                    paddingLeft:5,
                    color:'#05375a' 
                 }}
              />
            </View>   
            {/* edit phone number and the address same textInput as name and email*/} 
             
             {/*Update Button*/}  
             {!uploading ?
             <View>
               <AppButton 
                 label="Update"
                onPress={updateProfile}
               />
             </View> 
              :<UploadProgress />
            }

问题分析与修复方案

1. 优先检查Firestore安全规则(核心原因)

Firestore免费试用到期后,默认安全规则会被调整为禁止未授权写入,甚至完全锁死写入操作。

  • 打开Firebase控制台 → 进入Firestore数据库 → 切换到「规则」标签页
  • 替换为允许认证用户修改自己文档的规则:
rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, update, delete: if request.auth != null && request.auth.uid == userId;
      allow create: if request.auth != null;
    }
  }
}

注意:不要用allow read, write: if true;这种宽松规则,会导致数据泄露风险。

2. 替换update()为set({merge: true})

update()要求文档必须存在,如果用户文档被误删或未初始化,就会触发「No document to update」错误。改用set并开启merge选项,文档不存在时会自动创建,存在时合并更新字段:

// 把updateProfile里的update代码改成下面这样
await db.collection("users")
  .doc(auth.currentUser.uid)
  .set({
    name: userData.name,
    email: userData.email,
    phone: userData.phone,
    address: userData.address,
    userImg: imgUrl // 这里要改成前面的imgUrl变量,不是userData.imgUrl
  }, { merge: true })

3. 修复uploadImage函数的返回值问题

当前uploadImage没有正确返回图片URL,导致imgUrl始终为空,而且字段名不统一(代码里既有imgUrl又有userImg)。修改成Promise风格,确保返回URL:

const uploadImage = async () => {
  if (image == null) {
    return userData?.userImg || ""; // 没有新图片时直接返回现有头像URL
  }
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onload = function () {
      const blob = xhr.response;
      const ref = firebase.storage().ref().child("images/" + new Date().toISOString());
      const snapshot = ref.put(blob);

      snapshot.on(
        firebase.storage.TaskEvent.STATE_CHANGED,
        () => setUploading(true),
        (error) => {
          setUploading(false);
          console.log(error);
          blob.close();
          reject(error);
        },
        () => {
          snapshot.snapshot.ref.getDownloadURL().then((url) => {
            setUserData(prev => ({...prev, userImg: url})); // 统一用userImg字段
            setUploading(false);
            blob.close();
            resolve(url); // 返回图片URL
          });
        }
      );
    };
    xhr.onerror = function () {
      reject(new TypeError("Network request failed"));
    };
    xhr.responseType = "blob";
    xhr.open("GET", image, true);
    xhr.send(null);
  });
}

4. 完善updateProfile的异常处理

加上用户未登录判断,以及数据库操作的错误捕获:

const updateProfile = async()=>{
  if (!auth.currentUser) {
    Alert.alert('提示', '用户未登录');
    return;
  }
  
  let imgUrl;
  try {
    imgUrl = await uploadImage();
  } catch (err) {
    console.log('图片上传失败', err);
    imgUrl = userData?.userImg;
  }

  try {
    await db.collection("users")
      .doc(auth.currentUser.uid)
      .set({
        name: userData?.name || "",
        email: userData?.email || "",
        phone: userData?.phone || "",
        address: userData?.address || "",
        userImg: imgUrl
      }, { merge: true });
    Alert.alert('成功', '资料更新完成');
  } catch (err) {
    console.log('更新失败', err);
    Alert.alert('错误', '更新资料时出错,请稍后重试');
  }
}

5. 检查Firebase配额使用情况

免费试用到期后,Firestore的写入配额会大幅降低,如果超出配额也会导致操作失败。进入Firebase控制台 → 使用情况 → Firestore,确认是否超出写入次数限制。


内容的提问来源于stack exchange,提问作者Bashamlan Salem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 09:45:28