简体   繁体   中英

Storing and retrieving a base64 encoded string in Firebase storage

I have a Base64 encoded string (this is AES encrypted string). I am trying to store it in Firebase Storage and then download it from it.

I have tried multiple options eg

pathReference.putString(data, 'base64')

This does not retain the the base64 string in storage but converts it into integers. I have also tried providing a {contentType: "application/Base64"} but putString doesn't seem to work.

I then tried making it a blob

blob = new Blob([data], {type: "application/Base64"})
await pathReference.put(blob)

With this I am able to get the base64 encoded string in storage (though there are newlines added in string)

When I download it with ES6 fetch I am not getting back the string

const url = await pathReference.getDownloadURL()
const response = await fetch(url)
const data = await response.blob()

Instead getting an error Unhandled promise rejection: URIError: URI error

I am just looking for a very simple upload and download sample for base64 encoded string to firebase storage.

Any help is greatly appreciated.

I was able to make it work, though some firebase / fetch with react-native behavior is still unclear.

To upload a base64 encoded string to firebase storage I used the following snippet.
Here "data" is already a Base64 encoded string.

const pathReference = storage.ref(myFirebaseStorageLocation)
const blob = new Blob([data], {type: "application/Base64"})
await pathReference.put(blob)

I verified the contents in Firebase storage and downloaded the file manually which also looked fine.

Then to download under a React Native, Expo project there were several roadblocks but what finally worked was this

  1. I had to add a btoa() function in global namespace.
  2. Used the following code to download and then read it back as a Base64 string (which was surprisingly hard to get to)

Code to download the file and read back as Base64 string.

const fetchAsBlob = url => fetch(url)
  .then(response => response.blob());

const convertBlobToBase64 = blob => new Promise((resolve, reject) => {
  const reader = new FileReader;
  reader.onerror = reject;
  reader.onload = () => {
    resolve(reader.result);
  };
  reader.readAsDataURL(blob);
});


const url = await pathReference.getDownloadURL()
const blob = await fetchAsBlob(url)
const doubleBase64EncodedFile = await convertBlobToBase64(blob)
const doubleEncodedBase64String = doubleBase64EncodedFile.split(',')[1]
const myBase64 = Base64.atob(doubleEncodedBase64String)

The caveat was that the FileReader reads the content and encodes it again into Base64 (so there is double encoding). I had to use the Base64.atob() to get back my original Base64 encoded string.

Again this may be unique to the situation where there is fetch being called under a React Native Expo project, both of which have some additional quirks when it comes to handling blobs or Base64.

(PS: I tried using response.blob(), response.buffer() and tried everything including libs to convert Blobs to Base64 strings but ran into one or the other issue, I also tried using Expo FileSystem, download file locally and read using FileSystem.readAsStringAsync, but it ran into native issues with iOS. tl;dr; the above solution worked but if someone can provide any explanation or clarity on all other attempts or a better solution then it will be greatly appreciated. Also unclear is why firebase storage putString(data, 'base64') does not work.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM