So I have set up AngularFire within my Angular 6 webapp, and have been trying to use the AngularFireStorage. I have followed the documentation correctly and have it uploading images as I can see in Firebase that the image is uploaded to the specific place and with the specific filePath I am giving. Here is the code:
uploadFile(e) {
const file = e.target.files[0];
const filePath = `test${this.uid}`;
const task = this.storage.upload(filePath, file);
const dlUrl = task.downloadURL();
dlUrl.subscribe((res) => {
console.log(res);
});
}
Whenever I am call console.log(res) it returns an undefined value. I have not once received an actual download URL from AngularFireStorage, just always returns undefined. I can verify that the correct image is uploaded into the storage bucket, and even if it has the same file name, it overwrites the old one. Just to be as clear as possible here is the <input> for the file:
<input type="file" accept=".jpg,.jpeg,.png;capture=camera" (change)="uploadFile($event)">
I am not sure what could be going wrong here as the image successfully uploads, I get zero errors in the console, but just always an undefined string gets returned. Any and all help is very appreciated, thanks in advance!
EDIT:
For anyone still following this post, I ended up just using the firebase methods and package and skipped angularfire2 for the storage features. Here is what I did in place of the angularfire2/storage methods.
I made an upload method in a service with a BehaviorSubject<number> to pass the percentage onto my component:
percentSubject: BehaviorSubject<number> = new BehaviorSubject(0);
constructor() { }
pushUpload(file) {
return new Promise((resolve, reject) => {
const storageRef = firebase.storage().ref();
const uploadRef = storageRef.child(`uploads/${file.name}`);
this.uploadTask = uploadRef.put(file);
this.uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED,
(snapshot: firebase.storage.UploadTaskSnapshot) => {
this.percentSubject.next((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
},
(error) => {
reject(error);
},
async () => {
const u = await this.uploadTask.snapshot.ref.getDownloadURL();
resolve(u);
}
);
});
}
This has worked everytime and passes back the correct downloadURL with the Promise.resolve. I would still like to hear if anyone can get the AngularFireStorage methods working as I am still confused as to why it returns undefined URLs. Hope this can be of help!
EDIT 2:
So after doing some research and looking through the angularfire2/storage module I noticed that it is using deprecated firebase methods that were removed starting with version 5.0.0. Here is the release notes: https://firebase.google.com/support/release-notes/js
If you go down to the 4.13.0 you will see that FullMetadata.downloadUrls and UploadTaskSnapshot.downloadUrl have been deprecated in favor of Reference.getDownloadUrl(). Looking through the angularfire2 package I noticed this line:
downloadURL: function () { return from(task.then(function (s) { return s.downloadURL; })); }
in the task.js file and realized it is using the old methods and since I am using firebase version 5.0.1 in my application, the variable has been removed and therefore will return undefined everytime. If that line in the angularfire2/storage/task.js file is changed to this:
downloadURL: function () { return from(task.then(async function (s) { return await s.ref.getDownloadURL(); })); }
It returns the correct URL for the uploaded image using Firebase 5+.
So If you want to use AngularFire2 for Storage ATM, make sure your Firebase version correlates with the AngularFire2 versions. Hope this can clear up anyone elses issues!
undefinedstring after making theObservable<string>globally available to the class. - Nicholas Pesa