fredg
August 8, 2018, 8:12am
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
gusds
August 8, 2018, 2:40pm
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.
1 Like
fredg
August 8, 2018, 3:01pm
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
gusds
August 8, 2018, 4:15pm
4
Use the Filesystem object:
fredg
August 8, 2018, 6:52pm
5
@gusds ,
FileSystem.readAsStringAsync can only read text files, not binary files.
Regards,
Fred
fredg
August 10, 2018, 1:52pm
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
thank you in advance for your help.
priezz
August 15, 2018, 10:15am
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)
}
1 Like
fredg
August 15, 2018, 10:59am
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
priezz
August 15, 2018, 1:21pm
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.
fredg
August 15, 2018, 2:58pm
10
Thanks for your recommendation
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
fredg
August 16, 2018, 7:34am
12
Thank you again for your help.
What package did you install for ‘base64-js’? base64-js - npm ?
Thanks
fredg
August 16, 2018, 12:16pm
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.
fredg
August 16, 2018, 2:55pm
14
I tried everything, I give up! I will have to detach Expo
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
system
Closed
August 31, 2018, 2:55pm
15
This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.