Reputation: 1361
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
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
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 typeapplication/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:
Upload files with Cloud storage on web
Upvotes: 4
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
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
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