angular - 使用 Firebase 存储和 Firebase 插入/更新用户个人资料图片
问题描述
当用户更新您的个人资料图片时,我需要将他的照片上传到 Firebase 存储并立即检索下载 URL 以更新他的个人资料集合。
在另一种情况下,当用户更新他的个人资料时,他并没有更改他的个人资料图片,所以我没有 imageData 也不需要上传他的图片,只需更新他的个人资料信息。
我的saveProfile()
方法:
if (this.profileForm.valid) {
....
//Check if the user change his picture. If yes, the userProfilePicture has data.
If (userProfilePicture) {
//upload the picture to firestorage
const path = `/profile/${this.profile.id}.jpg`;
const task = this.afStorage
.ref(path)
.putString(imageData, 'base64', { contentType: 'image/jpeg' });
// subscribe to download url
task.downloadURL().subscribe(
url => {
//updating profileUrl in the form
this.profileForm.patchValue({ avatar: url });
//Doing the update in Firestore
this.afs.doc(`/profile/${id}`).update(this.profileForm.value);
});
}
Else {
// just update the profile information
this.afs.doc(`/profile/${id}`).update(this.profileForm.value);
}
}
我想避免重复更新代码。有没有更方便的方法来实现这一点?也许,如果我在有可用的 downloadUrl(在 2 种情况下)时进行更新,如下所示:
If (userProfilePicture) {
//upload the picture
//subscribe to get the download url
}
//AWAIT for the subscribe to return the download URL and when the download URL is available then update
?? How to do this
//update the profile information with the new or existent download URL
await??? this.afs.doc(`/profile/${id}`).update(this.profileForm.value);
解决方案
FYI downloadURL()
on task 在 5.0 中已贬值,您需要在上传完成后使用 ref 上的那个;所以你需要保留对它的引用:
const path = `/profile/${this.profile.id}.jpg`;
const ref = this.afStorage.ref(path);
const task = ref.putString(imageData, 'base64', { contentType: 'image/jpeg' });
task.snapshotChanges().pipe(
filter(snap => snap.state === storage.TaskState.SUCCESS)
switchMap(() => ref.getDownloadURL())
).subscribe(url => {
...
})
至于减少重复代码,只要使用更新就可以了;因为这只会更新指定的字段。只需将个人资料图片留在 profileForm 之外。
// if there's a profile picture to upload, do so
if (userProfilePicture) {
const path = `/profile/${this.profile.id}.jpg`;
const ref = this.afStorage.ref(path);
const task = ref.putString(imageData, 'base64', { contentType: 'image/jpeg' });
task.snapshotChanges().pipe(
filter(snap => snap.state === storage.TaskState.SUCCESS)
switchMap(() => ref.getDownloadURL())
).subscribe(profilePicture => {
this.afs.doc(`/profile/${id}`).update({profilePicture});
})
}
// also just update the rest of the profile, update is non-destructive and only overwrites the fields specified
this.afs.doc(`/profile/${id}`).update(this.profileForm.value);
推荐阅读
- html - 根据条件显示隐藏行
- qt - ComboBox QML 中的弹跳效果
- python - 如何堆叠两个numpy数组的每n行
- amazon-web-services - 跨帐户+跨区域代码管道出现错误
- ternary - 这种奇怪的 OR 和三元输出的原因是什么 [Javascript]
- testng - @DataProvider 返回类型为迭代器
- javascript - 使用 jQuery 更改 location.href
- azure - 阻止与微服务相关的 AKS 公共 URL 并保留它们以供内部通信
- api - Icinga2 事件插件命令通过 api 启动 rundeck 作业
- python - Azure:使用 Python 脚本在 virtual_network 类中检索“address_space”