在努力将图片上传到 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 存储,而无需点击上传按钮。
答案 0 :(得分:0)
你能用这个代码试试吗:
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();
}, []);