I’m making an attempt to make an app that permits customers to take footage with their gadget digicam (ios for now) after which have that auto add to set of occasions in firebase. The add ought to both occur within the background (ideally) or queue for add when the consumer subsequent opens the app to the foreground
I’ve tried just a few various things:
- I’ve tried having it so the replace images callback on the medialibrary listener updates an inventory of photos in async storage, after which the uploader uploads from that listing and tracks uploads with one other uploaded listing in async storage. The uploader ran each X seconds
- I’ve tried to make use of a number of job queue libraries, couldnt get any to work (this seems like it could be the most suitable choice because the listener may create a job to add after which the add may tick off one after the other)
- I’ve additionally tried making my very own make-shift uploader (see code beneath)
most of my efforts enable me to efficiently add photos to my chosen occasions, however the app crashes if I take too many footage without delay. It is also considerably unreliable within the background.
I’d actually respect any recommendation or any assist anybody can provide, I’m pretty new to react-native.
Additionally I’m utilizing expo-router, so I’ve the code in my _layout in order that it runs on all pages of my app when isLive is triggered, is that advisable? Please let me know when you want additional clarification
Under id the third try described above, making an attempt to make my very own makeshift uploader:
import React, { createContext, useState, useEffect, useRef } from "react";
import { Slot } from "expo-router";
import { useFonts } from "expo-font";
import {
Montserrat_400Regular,
Montserrat_400Regular_Italic,
Montserrat_600SemiBold,
} from "@expo-google-fonts/montserrat";
import * as MediaLibrary from "expo-media-library";
import AsyncStorage from "@react-native-async-storage/async-storage";
import uploadImageToEvents from "../companies/uploadImageToEvents";
import EventListeners from "../companies/EventListeners";
export const AppContext = createContext(null);
perform FontLoader({ youngsters }) {
const [loadedFonts] = useFonts({
MontserratRegular: Montserrat_400Regular,
MontserratItalic: Montserrat_400Regular_Italic,
MontserratSemiBold: Montserrat_600SemiBold,
});
if (!loadedFonts) {
return null;
}
return youngsters;
}
export default perform HomeLayout() {
const [userDetails, setUserDetails] = useState<UserDetails>(
{} as UserDetails
);
const [userEvents, setUserEvents] = useState<UserEvents>({} as UserEvents);
const [selectedEvent, setSelectedEvent] = useState({});
const [homeTabState, setHomeTabState] = useState<HomeTabState>("reminiscences");
const [isLive, setIsLive] = useState(false);
const [liveEventIds, setLiveEventIds] = useState([]);
const uploadQueue = useRef([]);
const [imagesToUpload, setImagesToUpload] = useState(false);
useEffect(() => {
setImagesToUpload(uploadQueue.present.size > 0);
}, [imagesToUpload]);
useEffect(() => {
if (!imagesToUpload || liveEventIds.size === 0) {
return;
}
const uploadImages = async () => {
const photoUris = uploadQueue.present.shift();
strive {
await uploadImageToEvents(photoUris, liveEventIds);
setImagesToUpload(false);
} catch (err) {
console.log(err);
}
};
uploadImages();
}, [imagesToUpload]);
const updatePhotos = async (insertedAssets: MediaLibrary.Asset[]) => {
strive {
const newUris = insertedAssets.map((asset) => asset.uri);
uploadQueue.present.push(newUris);
setImagesToUpload(true);
} catch (err) {
alert(err);
}
};
useEffect(() => {
let newSubscription: MediaLibrary.Subscription | null = null;
(async () => {
strive {
if (isLive) {
const { standing } = await MediaLibrary.requestPermissionsAsync();
if (standing !== "granted") {
alert("Person must grant permission to images.");
return;
}
newSubscription = MediaLibrary.addListener(
async (occasion: MediaLibrary.MediaLibraryAssetsChangeEvent) => {
await updatePhotos(occasion.insertedAssets);
}
);
} else {
newSubscription?.take away();
}
} catch (err) {
alert(err);
}
})();
return () => {
newSubscription?.take away();
};
}, [isLive]);
return (
<FontLoader>
<AppContext.Supplier
worth={{
userDetails,
setUserDetails,
userEvents,
setUserEvents,
selectedEvent,
setSelectedEvent,
homeTabState,
setHomeTabState,
}}
>
<EventListeners
occasions={userEvents}
setIsLive={setIsLive}
setLiveEventIds={setLiveEventIds}
/>
<Slot />
</AppContext.Supplier>
</FontLoader>
);
}