Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save a copy of an image (located at a URL) to Firebase Storage (web) using Javascript?

I'm trying to create a copy of an image (which is located at a url), and save it to Firebase's storage facility. I want to store the actual image file and not just the url. If I understand correctly, I first need to convert the image at the url to a blob or file and then upload the data to the Firebase storage.

This is my current attempt with Javascript:

function savePicture(){
    var url = ["http://carltonvet.com.au/sites/default/files/styles/large/public/images/article/cats.jpg"];
    var blobpic = new Blob(url, {type: 'file'}); 
    console.log(blobpic);

    var user = firebase.auth().currentUser;
        if (user != null) {
            var userid = user.uid; 

            var ref = firebase.storage().ref(userid + "profilePhoto");
            ref.put(blobpic).then(function(snapshot) {
                console.log('Picture is uploaded!');
                console.log(snapshot);

                var filePath = snapshot.metadata.fullPath;
                document.getElementById('picTestAddress').innerHTML = ""+filePath;
                document.getElementById('picTestImage').src = ""+filePath;
        });
        }else{
                console.log("Something went wrong, user is null.");
        }
}

I have two HTML tags like this:

<div id="picTestAddress"></div>
<img id="picTestImage" />

I'm pretty sure this is only saving the url and not the physical image.

The "picTestAddress" gets filled in with "qAjnfi387DHhd389D9j3r/profilePhoto", and the console shows the following error for "picTestImage": GET file:///android_asset/www/qAjnfi387DHhd389D9j3r/profilePhoto net::ERR_FILE_NOT_FOUND

I'm using Firebase for Web and Cordova. And I'm testing the app on my android phone.

I understand that the error is because it's looking for the image on my phone's local file system. This makes sense to me, so I thought I could fix this by appending my app's address to the beginning of the filePath (eg: document.getElementById('picTestImage').src = "https://firebasestorage.googleapis.com/v0/b/MY_APP.appspot.com/o/"+filePath;).

To find the correct path, I navigated to the file's location in the Firebase console and copied the "Download url" address - but when I checked this (by entering it into my web browser) it loaded a white page which contained one line of text, which was the original url: "http://carltonvet.com.au/sites/default/files/styles/large/public/images/article/cats.jpg"

So now I think I've just saved the url to the storage instead of the actual image file.

I've been following the Firebase docs, and I think I have the uploading part working correctly, but I think I'm failing when it comes to converting the url to the blob/file with Javascript.

I've looked through some other questions, such as this one: How to store and view images on firebase? and was going to follow the example here: https://github.com/firebase/firepano but it says that it's now a legacy example and I can't seem to find an updated version in Firebase's samples section.

Any advice or help with how to do this would be really appreciated. Thank you in advance!

like image 604
Emily Avatar asked Feb 05 '23 11:02

Emily


1 Answers

Looks good, though I'd also consider a promisified version:

function getBlob(url) {
  return new Promise(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function(event){
      var blob = xhr.response;
      resolve(blob);
    };
    xhr.onerror = reject();
    xhr.open('GET', url);
    xhr.send();
  }
}

function storageURLForPhoto(oldURL, newName) {
  getBlob(oldURL)
  .then(function(blob) {
    var picRef = firebase.storage().ref().child(newName);
    return picRef.put(blob)
  })
  .then(function(snapshot) {
    return snapshot.downloadURL;
  });
  .catch(function() {
    // handle any errors
  })
}

Little easier to reason about :)

like image 72
Mike McDonald Avatar answered Feb 08 '23 12:02

Mike McDonald