wkh237 / rn-firebase-storage-upload-sample

React Native sample code for upload blob data to Firebase using Firebase SDK with RNFetchBlob.
57 stars 13 forks source link

Crashes with larger files (256kb) #2

Closed rzmz closed 7 years ago

rzmz commented 7 years ago

Hi! Nice project, works all fine with the default sample image. But crashes with a larger image.

For an example: change https://avatars0.githubusercontent.com/u/5063785?v=3&s=460 to https://www.voog.com/images/frontpage-catch.jpg and you'll get an unknown firebase error. And that later image is only some 500kb.

wkh237 commented 7 years ago

Hi @rzmz , thanks for the information, does this happens on both Android and IOS ? I'll do some test on it.

rzmz commented 7 years ago

Happens on IOS, I tested with fetching over https and also with a local image. If I crop that image to about 200kb, it uploads nicely to firebase so the config is ok. I haven't tried it on Android.

wkh237 commented 7 years ago

I've tested on both platform. Looks like FireBase SDK uses different strategy when uploading small and large files, I'll try to fix it, thank you.

wkh237 commented 7 years ago

@rzmz , I somehow solved the problem, this is a little complicated.

FireBase uses different strategy when uploading file to storage, I think the threshold is 256kb. When a file is smaller than the threshold, they send the file in single request, otherwise the file got split into 256kb chunks and upload then using their own protocol.

The problem is, in order to split the file into chunks, it uses Blob.slice() which is a standard API that I haven't implemented due to React Native restriction. From my understanding, React Native does not allow us register a synchronous native method.

However, I still implemented Blob.slice() which pretends it's synchronous, and add a check mechanism to XMLHttpRequest.send so that it will always send request after its body created, I think this solution is good enough to fulfill the Firebase's use case ATM.

Here's the result :

2016-08-14 9 51 49

I haven't finish the Android part, but I think it won't take too much time. I'll publish a dev release once it's done.

wkh237 commented 7 years ago

I've just published a new version 0.9.2-beta.1, to use this version install the package via following commands

$ rnpm uninstall react-native-fetch-blob
$ npm install --save react-native-fetch-blob@beta && rnpm link

Restart packager and recompile the project.

rzmz commented 7 years ago

Thank you so much, it is working now seamlessly.

shilpan commented 7 years ago

@wkh237 do you have a timeline on when the android side of this will be implemented? This is a savior. I was fretting I won't be able to use firebase storage on RN until I saw this. Kudos to you :)

wkh237 commented 7 years ago

@shilpan , you can try to use dev version 0.9.2-beta.1, but I'm not sure if it works properly or not.

apurv commented 7 years ago

@wkh237 thank you so much for the fix, I've been banging my head on this for last couple days. Its working flawlessly now on iOS, can anyone confirm if Android is good to go as well?

wkh237 commented 7 years ago

@apurv , the Android part already finished in 0.9.2-beta.1, it had passed test cases on the new features. However, I'm quite busy at my work these days :weary: and I'd like to know more feedback and do more test about the new version before formal release. If you can try the beta version and give us some feedback that'd be grateful :grimacing:

shilpan commented 7 years ago

@wkh237 I have a performance question. Do you do slicing after transferring the binary over the bridge or natively? When you pass wrap the binary and pass it to Firebase does the upload happen in js context or natively? Essentially I want to know if I have a 10mb binary, will this method work or will it freeze up the app.

wkh237 commented 7 years ago

@shilpan , the upload process is done by fs and network API which uses a thread pool.