How to convert a file into base64 string in react native?


#1

Hi all,

I am trying to convert a file (pdf, word, excel, image, text) into a base64 string in react-native. After converting into a base64 string I just want to send it on the server.
I have to detach expo?
Can you help me to find out the solutions?

Thank you in advance for your help.

Fred


#2

JS solution:

// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9\+\/\=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/\r\n/g,"\n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}

// Define the string
var string = 'Hello World!';

// Encode the String
var encodedString = Base64.encode(string);
console.log(encodedString); // Outputs: "SGVsbG8gV29ybGQh"

// Decode the String
var decodedString = Base64.decode(encodedString);
console.log(decodedString); // Outputs: "Hello World!"

Credit where credit is due

Have you tried multer on server to receive files? Your react native code might use a simple fetch to upload files and avoid xxl base64 strings.


#3

@gusds,

Thank you for your answer.
The problem is that I can not read a binary file (pdf, word, excel,…) with expo.
Do you have a solution?

Regards,

Fred


#4

Use the Filesystem object:

https://docs.expo.io/versions/latest/sdk/filesystem


#5

@gusds,

FileSystem.readAsStringAsync can only read text files, not binary files.

Regards,

Fred


#6

Hi,

After doing some tests, I confirm that the FileSystem.readAsStringAsync function does not work with a binary file. Someone would have a solution?

I’m afraid I’ll have to detach Expo of my project :frowning:

thank you in advance for your help.


#7

It does. This is the routine I use to deal with binary files (images, etc.):

import base64 from 'base64-js'
import {FileSystem} from 'expo'


function stringToUint8Array(str: string) {
    const length = str.length
    const array = new Uint8Array(new ArrayBuffer(length))
    for(let i = 0; i < length; i++) array[i] = str.charCodeAt(i)
    return array
}

export async function fileToBase64(uri: string) {
    try {
        const content = await FileSystem.readAsStringAsync(uri)
        return base64.fromByteArray(stringToUint8Array(content))
    } catch(e) {
        console.warn('fileToBase64()', e.message)
        return ''
    }
}

/* Accepts 'rawFile' file object or the data 'uri' */
export function fileToBase64Helper(rawFile: any, uri: string) {
    return fileToBase64(rawFile ? rawFile : uri)
}

Read Binary file as Base64
#8

Hi priezz,

Thank you for your help.
I have unfortunately started to detach the project and it is not really easy! I have been working there for two days!

Best regards,

Fred


#9

My recommendation is revart back to non-detached option if you do not plan to use any native functionality, not provided by Expo. Working with the detached expo is really huge pain in the ass. I do almost for a year already (before that worked with plain RN for about 2 years) and would never recommend this approach. But I have no choice as I use lots of fitness APIs.

If you have just started your mobile development jorney, look at Flutter. Despite the fact, that it is much yonger, than RN and it’s ecosystem is not so large, the development process is much more smooth and predictable.


#10

Thanks for your recommendation :slight_smile:
Does your fileToBase64 function work on iOS? During my tests I had an error when I was trying to read a Word file on iOS with FileSystem.readAsStringAsync function


#11

yes, it does


#12

Thank you again for your help.
What package did you install for ‘base64-js’? https://www.npmjs.com/package/base64-js?
Thanks


#13

Here is the error that I reproduced during my tests on iOS with FileSystem.readAsStringAsync:

File ‘file:///var/mobile/Containers/Data/Application/6FE90D1C-98B0-450F-9BC4-02CE120C6A76/Documents/ExponentExperienceData/%2540fredg%252FRMS/documents/A7318582-9147-4146-B892-CFEF9C679079.doc’ could not be read.

The file exists because the FileSystem.getInfoAsync(filePath).then(({exists}) function returns true.


#14

I tried everything, I give up! I will have to detach Expo :cry:
The function can not read binary files.
When I read a text file, there is no error.
This is confirmed in the topic: Using Expo.FileSystem to save images to disk, from zip file


closed #15

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.