【问题标题】:React Native Expo : ulpoad Image to firabse Storage immediatley after the user Selects itReact Native Expo:用户选择后立即将图像上传到firebase存储
【发布时间】:2021-08-01 18:08:33
【问题描述】:

在努力将图像上传到 Firebase 存储并将其保存到用户 Firebase firestore 之后,我终于成功实现了。

我是这样做的:

  const [image, setImage] = useState(null);
  const [userData, setUserData] = useState("");

  const [uploading, setUploading] = useState("");
  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 () => {
    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";
      xhr.open("GET", image, true);
      xhr.send(null);
    });
  };

  // here I am uploading the image to 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();
  }, []);

我的问题是用户首先选择一张图片,然后他应该按上传按钮将其上传到 Firebase 存储,最后单击更新按钮以更新 Firestore 中的图片。 因为我希望用户能够在选择图像后立即将图像上传到 Firebase 存储,而无需单击上传按钮。

【问题讨论】:

    标签: javascript firebase react-native expo react-native-firebase


    【解决方案1】:

    你能用这段代码试试吗:

    const [image, setImage] = useState(null);
    const [userData, setUserData] = useState("");
    
    const [uploading, setUploading] = useState("");
    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 () => {
      let result = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: ImagePicker.MediaTypeOptions.All,
        allowsEditing: true,
        aspect: [4, 3],
        quality: 1,
      });
      if (!result.cancelled) {
        UpdateImage(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";
        xhr.open("GET", image, true);
        xhr.send(null);
      });
    };
    
    // here I am uploading the image to firebase storage
    const uploadImageToBucket = async (img) => {
      let blob;
      try {
        setUploading(true);
        blob = await getPictureBlob(img);
    
        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 (img) => {
      setImage(result.uri);
      let imgUrl = await uploadImageToBucket(img);
      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();
    }, []);
    
    

    【讨论】:

    • 它不起作用,因为图像需要先上传然后更新
    • 但您正在使用UpdateImage 调用uploadImageToBucket 上传图片
    • 嗯。抱歉,我才注意到这一点。感谢您的帮助和时间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2021-06-07
    • 2020-03-06
    • 2021-11-30
    • 2020-03-23
    • 2020-06-30
    • 1970-01-01
    相关资源
    最近更新 更多