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

React Native Expo:用户选中图片后立即上传至Firebase Storage实现问题

实现方案

只需新增一个监听image状态变化的副作用钩子即可实现选中图片后自动上传,具体修改如下:

调整点说明

  • 修正uploading状态的初始值:原代码初始设为空字符串,不符合布尔类型使用逻辑,改为false
  • 新增依赖image的useEffect:当image被赋值为有效图片uri时,自动触发上传+更新Firestore全流程
  • 可选优化:修复getPictureBlob方法硬编码使用外部image变量的问题,改为使用入参uri,逻辑更严谨;同时加上传中判定避免重复触发选图

修改后完整代码

const [image, setImage] = useState(null);
const [userData, setUserData] = useState("");
// 修正初始值为布尔类型
const [uploading, setUploading] = useState(false);

const getPermission = async () => {
  if (Platform.OS !== "web") {
    const { status } =
      await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (status !== "granted") {
      alert("Sorry, we need camera roll permissions to make this work!");
    }
  }
};
const getUserData = async () => {
  await firebase
    .firestore()
    .collection("users")
    .doc(firebase.auth().currentUser.uid)
    .get()
    .then((documentSnapshot) => {
      if (documentSnapshot.exists) {
        setUserData(documentSnapshot.data());
      }
    });
};

const pickImage = async () => {
  // 上传中禁止重复选图
  if (uploading) return
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
  });
  if (!result.cancelled) {
    setImage(result.uri);
  }
};

const getPictureBlob = (uri) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.onload = function () {
      resolve(xhr.response);
    };
    xhr.onerror = function (e) {
      reject(new TypeError("Network request failed"));
    };
    xhr.responseType = "blob";
    // 修复硬编码问题,改用入参uri
    xhr.open("GET", uri, true);
    xhr.send(null);
  });
};

// 上传图片到firebase storage
const uploadImageToBucket = async () => {
  let blob;
  try {
    setUploading(true);
    blob = await getPictureBlob(image);

    const ref = await storage.ref().child(uuid.v4());
    const snapshot = await ref.put(blob);
    console.log("link path");
    return await snapshot.ref.getDownloadURL();
  } catch (e) {
    alert(e.message);
  } finally {
    blob.close();
    setUploading(false);
  }
};

const UpdateImage = async () => {
  let imgUrl = await uploadImageToBucket();
  if (imgUrl === null && userData.photoURL) {
    imgUrl = userData.photoURL;
  }
  firebase
    .firestore()
    .collection("users")
    .doc(firebase.auth().currentUser.uid)
    .update({
      photoURL: imgUrl,
    })
    .then(() => console.log("user Upadted"));
};

useEffect(() => {
  getPermission();
}, []);
useEffect(() => {
  getUserData();
}, []);
// 新增监听image变化的副作用,选中图片后自动上传
useEffect(() => {
  if (image) {
    UpdateImage()
  }
}, [image])

调整后用户选中图片确认后,setImage触发状态更新,就会自动执行上传逻辑,不需要额外点击上传、更新按钮。

内容的提问来源于stack exchange,提问作者houcin olmostaf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 06:57:02