Zizazorro
Zizazorro

Reputation: 1361

Upload a base64 image with Firebase Storage

I'm making this app where users can have a profile picture (but only one picture each). I got everything set up, but when the pictures are 2mb+, it takes some time to load and actually I just need the pictures to be 50kb or so (only small display of pictures, max 40 pixels). I made some code to put the images directly into the realtime database (convert to canvas and make them a 7kb base64 string). However, this is not really clean and it's better to use Firebase Storage.

Since the new update 3.3.0 you can upload Base64 formatted strings to Storage, using the putString() method. However, when I upload my canvas image (which starts with "data:image/jpeg;base64,"), I get the error:

v {code: "storage/invalid-format", message: "Firebase Storage: String does not match format 'base64': Invalid character found", serverResponse: null, name: "FirebaseError"}.

Does this error occur because of string of the canvas image in the beginning? I've searched all over Stack, but I can't seem to find the answer.

Upvotes: 21

Views: 36145

Answers (5)

Big_Boulard
Big_Boulard

Reputation: 1355

uploadString if you're using modules, otherwise putString according to the doc

import { getStorage, ref, uploadString } from "firebase/storage";

const storage = getStorage();
const storageRef = ref(storage, 'some-child');

// Base64 formatted string
const message2 = '5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
uploadString(storageRef, message2, 'base64').then((snapshot) => {
  console.log('Uploaded a base64 string!');
});

// Base64url formatted string
const message3 = '5b6p5Y-344GX44G-44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
uploadString(storageRef, message3, 'base64url').then((snapshot) => {
  console.log('Uploaded a base64url string!');
});

// Data URL string
const message4 = 'data:text/plain;base64,5b6p5Y+344GX44G+44GX44Gf77yB44GK44KB44Gn44Go44GG77yB';
uploadString(storageRef, message4, 'data_url').then((snapshot) => {
  console.log('Uploaded a data_url string!');
});

Upvotes: 3

Dharmaraj
Dharmaraj

Reputation: 50930

When using the putString method, you just need to pass in the data part only which is separated from the preceding (media type) part by a comma. You also need to specify the contentType yourself else by default Firebase storage sets it to application/octet-stream and your file will be downloaded instead of rendering if you paste the URL in a browser.

If no contentType metadata is specified and the file doesn't have a file extension, Cloud Storage defaults to the type application/octet-stream

const base64str = "data:image/png;base64,....."
firebase
  .storage()
  .ref('path/to/image.png') // specify filename with extension 
  .putString(base64str.split(',')[1], "base64", {contentType: 'image/png'})
// specifying contentType                        ^^^

References:

Base64 Wikipedia

Upload files with Cloud storage on web

Upvotes: 4

mheavers
mheavers

Reputation: 30188

Looks like they have a method in the docs for base64 images that doesn't require you to manually replace the data:image... part:

ref.putString(message, 'data_url').then(function(snapshot) {
  console.log('Uploaded a data_url string!');
});

Upvotes: 10

Khrystyna Skvarok
Khrystyna Skvarok

Reputation: 1198

I actually had the same problem and solved it by using putString(message, 'base64') and cutting off data:image/jpeg;base64,.

The method for uploading Base64url formatted string putString(message, 'base64url') didn't work for me. It returned me the same Error as you have. Try using putString(message, 'base64'). Hope it helps!

Upvotes: 7

Zizazorro
Zizazorro

Reputation: 1361

Jeez, I've been busy for a very long time now, but just after I posted this, I've found the answer myself. The solution was to get the base64 variable and remove the first 23 digits (so: "data:image/jpeg;base64,") and upload it to the Firebase Storage. Now it gets accepted and you can put the link in your Realtime Database via:

var storageRef = firebase.storage().ref().child("Whatever your path is in Firebase Storage");
var imageRef = "Your path in the Realtime Database";

    storageRef.getDownloadURL().then(function(url) {
        imageRef.child("image").set(url);
    }); 

    var task = storageRef.putString("Your base64 string substring variable", 'base64').then(function(snapshot) {
         console.log('Uploaded a base64 string!');
         });

Upvotes: 17

Related Questions