-
Notifications
You must be signed in to change notification settings - Fork 927
uploadBytes to storage with expo Image picker causing app to crash with no logs #5848
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Hello! In order to solve your issue, I first recommend that you update to the latest version of firebase (v9) within your Expo application. Then, watch this video: https://www.youtube.com/watch?v=H-yXO46WDak . Very recent video so it incorporates version 9 and also should solve your issue because it also tries to upload image to firebase storage. Hope this helps! |
When looking at your code, I believe that it is the method that you use to generate the blob is complicated and prone to errors. Reference the video I just sent to see how I recommend you turn your image into a blob. |
@Eesha-Jain Your YouTube code works for images through ImagePicker but not for videos. It always crashes on iOS videos. Android videos go through just fine. |
Ohh, alright. Looks like this may hold a solution: expo/expo#3177 |
@rgioeli hey, I am having the same issue - did you end up finding a solution that worked for you? |
I downgraded to v8 of firebase sdk, that worked for me. Not sure if it's an option for you, but maybe for other people reading this. As described in the comment at https://www.youtube.com/watch?v=H-yXO46WDak&lc=UgwNOcXKFQl2UARHz6Z4AaABAg.9Wqk13KYbzW9WuNC4HWz_s |
@pfibbe I just saw that mentioned somewhere else as well - seems like the way to go. Thanks! |
Thanks for the info that this works with 8.10.0 and not in 9.6.1. Would anybody be able to try and see if this is also broken in any earlier v9 builds, such as 9.2.0 perhaps? It would help us narrow down when the relevant change happened. |
I was actually using 9.2.0 when I came across the issue. |
Does the error also occur in 9.0.0? |
Unsure - unfortunately, I won't be able to check for a while, sorry. |
I would recommend going to 8.10.0 cause we're sure that works |
However, trying won't do any harm! :) |
Same issue, some video files fail randomly. |
If anyone can confirm the error also occurs in 9.0.0 and does not occur in 8.10.0, it will help us a lot in narrowing down the change that caused it. |
I will test it now with specific version of 9.0.0. It was definitely not working with ^9.2.0, then I switched back to 8.10.0 as mentioned here) and it was not working either. That being said, only with certain videos. Probably, as mentioned coz of memory issues with not small videos.
|
Hello, everyone i also faced the same issue, on firebase version 9.6.5, so i have used function uploadBytesResumable instead of uploadBytes, it works just fine, if it is urgent you can use that function for the time being, just a recommendation, for reference:- I faced this issue in iOS 15 and 15 + only, rest below iOS 15 and in android OS uploadBytes is working fine. Note:- when using XMLHttpRequest with uploadBytesResumable, first time image uploads smoothly on iOS 15.2 then, on uploading it on second time there is crash while uploading image. To avoid it use, this way we can also get blob file;
|
well i was using v9.4 then i upgrade it to latest version. i was able to upload file less than 2mb ... greater files will make the app crash so i went down to version 9.0.0 and i was able to upload files at 100mb+ so i think this issue related to newer versions of firebase. |
Will keep trying to dig into this but so far it seems that this error:
It seems 2 and 3 may be viable workarounds for the time being if anyone is blocked. As far as more info about versions affected, it seems to affect:
Feel free to chime in with any corrections, updates, or other workarounds. We will try to keep looking for what might have caused this in the Firebase SDK. |
I am experiencing this issue as well.
I have pinpointed that I can rollback to Firebase JS SDK 9.3.0 and everything works as expected, but upgrading to 9.4.1 - 9.6.6 causes the failure to occur. So for our experience it's something introduced between 9.3.0 and 9.4.1. |
The code that i wrote above is running fine on my mac but when complied from my colleague's pc created the same issue. We were still not able to resolve it by downgrading firebase version. I don't think issue lies in firebase sdk. It's just that it is not compatible with iOS 15 ?? + (because i only faced this issue in iOS 15). Maybe a support for iOS 15 needs to be added as iOS 15 has come up with major updations. Just a guess. Try to solve issue by changing firebase version and maybe compiling your code on other device. I will still recommend to use uploadResumable bytes and fetch. |
How would i rollback to a different version of FIREBASE? |
|
Been using the above code to upload images to firebase (version 9.6.6). Works perfectly with one image, but cannot upload multiple images. Any suggestions? Have tried using await and .then() to try looping, but that has not worked either. |
So we have one report that the bug occurred in 9.2.0, and a separate report that it did not occur in 9.3.0 but did occur in 9.4.1, which seems confusing to me. Any additional data about what versions the error is or isn't happening would be helpful in sorting out what changes to look at. |
Use this code to get blob file instead of XMLHttpRequest |
I can confirm that I stepped through minor versions one-by-one until it started occurring and it first started in 9.4 This is on managed Expo app served through the Expo app. The impact on iOS it uploads for a bit then crashes without error. On Android, it uploads for a bit then hangs forever without error. This testing was done on real devices, not simulators. I only stepped through the individual versions within the Expo app but can also verify it worked in 9.0 when deployed through the official stores, and was broken in 9.6. On both platforms. |
Hello, I'm having the same issue, but I might be able to add some insight. Here is my current takePicture function:
I'm also using the Full Example from the Firebase Upload Files documentation. With the current options, I am able to upload both images from the camera to Firebase. However, if I remove the quality option, the upload fails 100% of the time. It would seem that the size of the file might cause uploadBytesResumable to crash. Using Firebase |
- see firebase/firebase-js-sdk#5848 (comment) Former-commit-id: 4863936 Former-commit-id: b95a269
Is this error, which, as far as I understand, is due to Expo and the file size, only occurring in development, or does it not work in production either? |
@ZackryPaul Thank you so much for this investigation. I and @maneesht have poured a lot of time into trying to debug this to no avail. I especially appreciate you discovering that this also happens in react-native-firebase which indicates that this isn't a bug in the JS SDK.
Even though it seems the JS SDK isn't causing this, we can try to look further into your solution to see if our code can fill in the metadata in a way that prevents the problem. Not sure off the top of my head how to do it, since we obviously can't force every image to be converted to PNG, but maybe if it's a missing/incorrect metadata issue we can figure out how to fill that in. |
Yes, I definitely don't think it's firebase itself causing this issue. After these changes, I haven't had a problem yet! I hope you guys get this worked out! |
but no one has put it into production yet to see if it works ? |
I don't think there should be any difference between dev and production? Are you seeing a difference? If so can you elaborate on your project setup and what the difference is between dev and production? I think you're the first person to mention a difference so it would be great if you could provide the details. |
I don't know, I'm just asking the question. I'm in the middle of development and I thought I understood that it was due to Expo, so I was asking if anyone else had the same problem in production and how people manage to make it work. |
This solution worked best for me. Check and compress if the size is larger than 1mb + uploadBytesResumable. Also the workaround for this Filesize of the images weirdly increased after fetching the blob and uploading it to Firebase Storage, so the compression essentially did nothing if I didn't use this workaround. |
Is there a solution without compressing that much pictures? |
Bumping this, since people still encounter this issue. This solution:
My app has been using this strategy for a year with thousands of uploaded photos. It just requires a few hours to set this up, and you can stay 100% within Expo and Firebase ecosystems. |
I have been facing this issue for one year, and the problems keep on and off. I would really recommend that just switch to using React Native Firebase. Although it takes a bit more time to set it up, but it will totally save you tons of time. |
@geoffcfchen So you haven't been running into any issues with React Native Firebase? ZackryPaul commented above that he was still having issues with either Expo or RNF so I never bothered to try the switch. If anyone wants a repo example ZacharyPauls suggestion, you can check my project here- https://github.com/ben-hamel/rn-the-scene-app-expo-version The main difference with mine was having to restrict down to 1MB max instead of 4MB and I set the width when compressing the image, which allowed me to keep compression at 0.9 so far. |
No, I haven't faced any issues since I switched to react-native-firebase. I feel that it is much more stable than Firebase JS SDK, but maybe I haven't tested all the functions thoroughly. |
The problem with doing it this way is that Firebase functions limit the amount of data you can send through http. I've been doing it this way for years and have always been limited to 10mb. More recently Gen2 is supposed to limit you to 32mb, but that is still a pretty huge limitation. We really need direct upload to work. |
@nickjuntilla That's a good point for video or other large format uploads. However, most people are coming to this thread to figure out a solution to image uploading, and going with solutions that involve compressing to 1MB. 32MB uploads with background availability is a huge win for that majority use case. |
Well it's good for people to understand the limitation either way. In any case people may also be pleased to know that as of firebase 10.1.0 this code works as is described in the video above:
I came here because using the bytes64 returned from the imagePicker was not working, but it appears firebase has fixed the upload issue as long as you covert it to a blob first. This will be more simple for a lot of people. Also I think it's important that people understand the 10mb/32mb http pipeline limits in firebase because it's an extremely hard issue to figure out if you aren't aware of it. There is no proper error message, it will just fail. It's not the server RAM, it's not busboy limits, it's not express, it's firebase functions. Maybe I'll save someone a month on that. |
I had the issues but fixed by adding timeout(1000) after "await response.blob()". I can't figure out why. It seems to me blob not completed even if "await response.blob()" returned. |
if anyone face this issue on const d = await cameraRef.current?.takePictureAsync({
base64: true,
skipProcessing: false,
});
if (!d) {
return;
}
const storage = getStorage(firebaseApp);
const storageRef = ref(storage, "avatars/4.png");
const res = await fetch(d.uri);
const blob = await res.blob();
uploadBytesResumable(storageRef, blob).then((sanpshoot) => {
console.log("uploaded");
}); |
Temporarily, saving image before creating Blob solves problem. I am using below code to create Blob: import { SaveFormat, manipulateAsync } from "expo-image-manipulator";
export default async function createBlobFromURI(uri: string): Promise<Blob> {
const localUri = await createLocalFile(uri);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.response);
} else {
reject(new Error(`Failed to fetch resource: ${xhr.statusText}`));
}
};
xhr.onerror = (e) => {
console.error("Failed to create blob from URI", e);
reject(new Error("Network error"));
};
xhr.responseType = "blob";
xhr.open("GET", localUri, true);
xhr.send();
});
}
export async function createLocalFile(uri: string) {
const result = await manipulateAsync(uri, [], {
format: SaveFormat.JPEG,
});
return result.uri;
} Also, my Image Picker setup is like below: await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [1, 1],
quality: 0.2,
}); And finally, I am sending image to Storage like below: const blob = await createBlobFromURI(image);
const path = `vegetables/carrot.jpg`;
const storageRef = ref(storage, path);
const uploadTask = uploadBytesResumable(storageRef, blob, {
contentType: "image/jpeg",
}); |
In my case, it's not an image file but it's a m3u8 file that I'm trying to upload to to Cloud Storage. const m3u8 = new Blob([STRING_VALUE], {
type: "audio/mpegurl",
});
const masterM3u8Ref = ref(storage, `my_m3u8.m3u8`);
await uploadBytesResumable(masterM3u8Ref, newMasterBlob, metadata); Just like described above for image cases; sometimes it works and mostly it doesn't... App silently crashes without any error. I can't believe that this issue has been lingering since more than 2 years now... How people can rely on Anyway; after hours and hours of investigation and research online; finally I applied "saving the file to the filesystem and read from there" strategy and got it working. const m3u8 = new Blob([STRING_VALUE], {
type: "audio/mpegurl",
});
// Disgusting workaround: https://github.com/firebase/firebase-js-sdk/issues/5848
const outurl = URL.createObjectURL(m3u8);
const masterM3u8Blob = await (await fetch(outurl)).blob()
const masterM3u8Ref = ref(storage, `my_m3u8.m3u8`);
await uploadBytesResumable(masterM3u8Ref, newMasterBlob, metadata); Now it works, but to be honest, I hate it. |
Well, as you mentioned, it’s the |
[REQUIRED] Describe your environment
System:
OS: macOS Sierra 10.12.6
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 12.16.2 - /usr/local/bin/node
npm: 6.14.4 - /usr/local/bin/npm
SDKs:
iOS SDK:
Platforms: iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0
npmPackages:
expo: ~44.0.0 => 44.0.1
react: 17.0.1 => 17.0.1
react-dom: 17.0.1 => 17.0.1
react-native: 0.64.3 => 0.64.3
react-native-web: 0.17.1 => 0.17.1
npmGlobalPackages:
expo-cli: 5.0.3
[REQUIRED] Describe the problem
I am using Expo Image picker to select an image, convert to blob, then the Firebase 9.0 SDK function uploadBytes to add the image to my storage bucket. Around 60-80% of the time, the uploadBytes function causes my app to crash with no errors or logs recorded. When the app does not crash, the upload to Storage is successful.
Similar code and crashing symptoms as: https://stackoverflow.com/questions/70528896/react-native-expo-image-picker-upload-image-to-firebase-storage-v9-crash
Steps to reproduce:
Relevant Code:
The text was updated successfully, but these errors were encountered: