# #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. Да. Извините, что я только что это заметил. Спасибо за вашу помощь и время