我在这个模块中的主要目标是将用户的个人资料图片上传到Firebase存储库中,并将照片URL存储到Firestore(云Firestore)中。
注:
userId: string;
fname: string;
studentId: string;
@ViewChild('filePicker') filePickerRef: ElementRef<HTMLInputElement>;
@Input() showPreview = true;
//The Selected Image in the File Explorer
selectedImage: any;
constructor(private auth: AuthService,
private afs: AngularFirestore,
private loadingCtrl: LoadingController,
private toaster: ToastController,
private storage: AngularFireStorage,
private popOverCtrl: PopoverController) { }
ngOnInit() {
this.profileEditSub = this.auth.user$.subscribe(user => {
this.userId = user.userId;
this.fname = user.userName;
this.studentId = user.userSchoolId;
this.selectedImage = user.userPhoto;
});
}
onSubmit(form: NgForm){
const user = form.value.fname;
const studentId = form.value.studentId;
this.onUpdateUser(user, studentId);
}//
async onUpdateUser(name: string, studentNo: string){
const loading = await this.loadingCtrl.create({
message: 'Updating...',
spinner: 'crescent',
showBackdrop: true
});
loading.present();
const imageUrl = await this.uploadFile(this.userId, this.selectedImage);
this.afs.collection('user').doc(this.userId).update({
'userName': name,
'userSchoolId': studentNo,
'userPhoto': imageUrl, // Photo URL from Firebase Storage will be saved in here.
'editedAt': Date.now()
})
.then(() => {
loading.dismiss();
this.toast('Update Success', 'success');
this.closePopOver();
})
.catch(error => {
loading.dismiss();
this.toast(error.message, 'danger');
})
}//
async uploadFile(id, files):Promise<any> {
if (files && files.length) {
try {
const task = await this.storage.ref('images').child(id).put(files[0]);
return this.storage.ref(`images/${id}`).getDownloadURL().toPromise();
} catch (error) {
console.log(error);
}
}
}
onPickImage() {
this.filePickerRef.nativeElement.click();
}
onFileChosen(event: Event) {
const pickedFile = (event.target as HTMLInputElement).files[0];
if (!pickedFile) {
return;
}
const fr = new FileReader();
fr.onload = () => {
const dataUrl = fr.result.toString();
this.selectedImage = dataUrl;
};
fr.readAsDataURL(pickedFile);
}
update-profile.component.html
<!-- For the Image -->
<div class="picker">
<img
class="img"
[src]="selectedImage"
*ngIf="selectedImage && showPreview"
>
</div>
<input type="file" accept=".jpg,.png" *ngIf="usePicker" #filePicker (change)="onFileChosen($event)"/>
<ion-button class="image-btn" (click)="onPickImage()">
<ion-icon name="camera" slot="icon-only"></ion-icon>
</ion-button>
<!-- Other Textual Information -->
<form #f="ngForm" (ngSubmit)="onSubmit(f)">
<ion-list lines="full">
<ion-item>
<ion-label position="floating">Full Name:</ion-label>
<ion-input name="fname" required type="text" [(ngModel)]="fname" #userCtrl="ngModel"></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">Student No:</ion-label>
<ion-input name="studentId" required type="number" [(ngModel)]="studentId" #studentIds="ngModel"></ion-input>
</ion-item>
<ion-button class="ion-margin" type="submit" expand="block" shape="round" [disabled]="!f.valid">Edit User</ion-button>
</ion-list>
</form>
在您的代码中,我注意到了一些事情。
标记的选定文件上使用this.selectedimage
变量(来自文件资源管理器的注释),但在下面的行中,您将其重新分配到FireStore中图像的存储引用。this.profileEditSub = this.auth.user$.subscribe((user) => {
...
this.selectedImage = user.userPhoto; // this line
});
>
为的
src
使用单独的变量,然后使用另一个变量存储文件选取器的当前值()。
update-profile.component.ts
currentImageUrl: string; // to store the downloadUrl of image to be displayed
selectedFiles: Array<File>; // to store selected files in the File Explorer
this.profileEditSub = this.auth.user$.subscribe(async (user) => {
...
/**
* you only store the storage reference (user.userPhoto) in firestore, not the download url,
* so you need to fetch it again
*/
this.currentImageUrl = await this.storage
.ref(user.userPhoto)
.getDownloadURL()
.toPromise();
});
onFileChosen(event: any) {
this.selectedFiles = event.target.files; // just assigns the selected file/s in <input> this.selectedFiles
}
async onSubmit() {
if (this.selectedFiles.length) {
// Get selected file
const file = this.selectedFiles[0];
// Get the fullPath in Storage after upload
const fullPathInStorage = await this.uploadImage(this.userId, file);
/**
* You can now store the fullPathInStorage in firestore
*
* afs.update(...)
*/
// Get the downloadUrl for the src of img
this.currentImageUrl = await this.storage
.ref(fullPathInStorage)
.getDownloadURL()
.toPromise();
}
}
async uploadImage(uid, file): Promise<string> {
/**
* You can add random number in file.name to avoid overwrites,
* or replace the file.name to a static string if you intend to overwrite
*/
const fileRef = this.storage.ref(uid).child(file.name);
// Upload file in reference
if (!!file) {
const result = await fileRef.put(file);
return result.ref.fullPath;
}
}
update-profile.component.html
<input type="file" (change)="onFileChosen($event)"/>
<img [src]="currentImageUrl" />
此外,err_name_not_resolved
可能只是由于网络不稳定。
我试图构建一个,它包括两个按钮,一个用于用相机拍照并上传到Firebase存储,另一个用于从Firebase存储下载图像并在上显示。 现在,我被上传功能卡住了。我可以把照片保存到应用程序目录中。我想上传保存的图片到Firebase存储。
我正试着上传一张照片,在被croppie剪切到GCS之后。gcs write(imageToUpload)方法失败,因为imageToUpload当前不是文件,而是Blob。有没有人知道一个办法让这件事成功?可能是python中一种将BLOB转换为文件的方法吗?可以从Croppie返回的图像类型有:1)画布,2)HTML,3)BLOB和4)Base64这里是文档(Ctrl-F“result”)。任
我试图获得这样的下载网址,但它没有得到正确的网址。我是Firebase的初学者,怎么做呢?
我尝试了DPZFlickr,它在尝试上传时返回以下内容: 检查Flickr API的响应,它与尝试Dantsu版本的phpFlickr时返回的结果相同,返回如下: 我卷了自己的卷曲,返回如下:
我收到代码为200的响应,但图像没有上传到服务器
操作步骤: ①在"图层管理"模块,选择一个带有数据的图层。 ②点击记录弹出窗口。 ③点击"上传图片"按钮。 ④可以添加标注地点的照片信息,支持从本地上传和选择网络上的图片以及历史图片。 ⑤选择图片,进行添加图片。 ⑥点击"绑定图片"按钮。 提示: ●目前一个网点支持上传20张照片。 ●每张图片大小不超过5M。 操作动图: [查看原图]