I am developing a timelapse camera app using Expo and React Native. The app captures images at regular intervals, stores them in the Expo file system (FileSystem.documentDirectory), and then uploads them to Firebase storage. However, I'm encountering an issue where the app crashes when the phone is offline for approximately 30 minutes. If the phone regains an internet connection within 25 minutes, everything works as expected without any crashes.
In more detail, the app follows this workflow:
Capture an image and save it in the FileSystem.documentDirectory. Attempt to upload the image to Firebase storage. After a certain time interval, the app checks for images in the document directory, converts them to blobs, and uploads them to Firebase storage. The local image files are deleted after successful upload. The problem occurs when the phone is offline for an extended period (around 30 minutes). If the phone regains an internet connection within the first 25 minutes, the app functions correctly. However, if it remains offline for more than 25 minutes, the app crashes and doesn't upload the images taken during the offline period.
const uploadImage = aync (photo, location, cameraID) => {
const storage = getStorage(app);
const uri = photo.uri
... ...
const storageRef = ref(storage, savePath + fileName);
... ...
await FileSystem.moveAsync({
from: uri,
to: FileSystem.documentDirectory + fileName,
});
await FileSystem.moveAsync({
from: uri,
to: FileSystem.documentDirectory + fileName,
});
try {
await uploadBytes(storageRef, blob);
// ToastAndroid.show("Photo uploaded successfully 1", ToastAndroid.SHORT);
const files = await FileSystem.readDirectoryAsync(FileSystem.documentDirectory);
if (files.length) {
files.forEach(async function (file) {
//get blob
const newBlob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function (e) {
console.log(e);
ToastAndroid.show("xhr onerror", ToastAndroid.LONG);
reject(new TypeError("Network request failed"));
};
xhr.responseType = "blob";
xhr.open("GET", FileSystem.documentDirectory + file, true);
xhr.send(null);
});
await uploadBytes(storageRef, newBlob);
//Then , delete this file.
await FileSystem.deleteAsync(FileSystem.documentDirectory + file);
ToastAndroid.show(`${file}`, ToastAndroid.SHORT);
console.log("file deleted");
});
}
// Delete the photo from the cache after moving it
await FileSystem.deleteAsync(uri, { idempotent: true });
ToastAndroid.show("Cache cleared 1", ToastAndroid.SHORT);
}
catch (e) {
console.log("Offline image url:", fileName);
ToastAndroid.show("offline image url", ToastAndroid.LONG);
}
}
Below is the code snippet that uses above uploadImage function.
const __takePicture = async () => {
const options = {
quality: 1, // Set the quality of the captured photo
};
try {
const photo = await camera.takePictureAsync(options);
await uploadImage(photo, location, cameraID);
} catch (error) {
console.error('err while uploading');
}
navigation.navigate("WaitingScreen", { "params": params });
}
I have implemented a timelapse camera app using React Native (Expo) where images are captured and uploaded to Firebase storage. However, when the phone is offline for more than 25 minutes, the app crashes.
What I tried:
Capturing images at regular intervals and storing them in the Expo FileSystem.documentDirectory. Attempting to upload images to Firebase storage using a Firebase storage reference. Checking for images in the document directory after a set time and uploading them as blobs to Firebase storage. Deleting the local image files after successful upload. What I expected: The app should handle offline scenarios gracefully and upload images to Firebase when an internet connection is restored, regardless of how long the phone has been offline.
What actually resulted: When the phone is offline for over 25 minutes, the app crashes, and images taken during the offline period are not uploaded to Firebase. This issue does not occur if the phone regains an internet connection within 25 minutes.