Реагируйте на собственную выставку : загружайте изображение в хранилище firabse сразу же после того, как пользователь выберет его

# #javascript #firebase #react-native #expo #react-native-firebase

Вопрос:

После попыток загрузить изображение в хранилище 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 amp;amp; 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 сразу после его выбора, не нажимая кнопку «Загрузить».

Ответ №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 amp;amp; 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();
}, []);

 

Комментарии:

1. это не сработало, потому что изображение нужно сначала загрузить, а затем обновить

2. но вы загружаете изображение в UpdateImage вызов с uploadImageToBucket

3. Да. Извините, что я только что это заметил. Спасибо за вашу помощь и время