Closed abdullahIsa closed 1 year ago
Also may i know how to implement BackgroundFetch.registerHeadlessTask(MyHeadlessTask);
in my code ? as i only want to start task if user is authenticated
New code note yet fully tested, want to know if correct
/* eslint-disable no-unreachable */
import React, {
useContext,
createContext,
useCallback,
useState,
useEffect,
} from 'react';
import BackgroundFetch from 'react-native-background-fetch';
import {backgroundDataGetter} from './accountHelper';
const DailyTaskHookContext = createContext({});
const taskCallback = async taskId => {
console.log('Background fetch started');
await backgroundDataGetter();
BackgroundFetch.finish(taskId);
console.log('Background fetch finished');
};
const onTimeout = async taskId => {
console.warn('[BackgroundFetch] TIMEOUT task: ', taskId);
BackgroundFetch.finish(taskId);
};
const synWithDb = () => {
BackgroundFetch.configure(
{
minimumFetchInterval: 15, // 15 minutes
stopOnTerminate: false,
enableHeadless: true,
forceAlarmManager: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY,
},
taskCallback,
onTimeout,
);
BackgroundFetch.start();
console.log('Background fetch initiated');
};
export const DailyTaskContextProvider = ({children}) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
useEffect(() => {
if (isAuthenticated) {
BackgroundFetch.registerHeadlessTask(synWithDb);
} else {
BackgroundFetch.stop();
console.log('Background fetch stopped');
}
return () => {
BackgroundFetch.stop();
};
}, [isAuthenticated]);
const startDailyTask = useCallback(async () => {
if (__DEV__ !== true) {
BackgroundFetch.stop();
setIsAuthenticated(true);
}
}, []);
const stopDailyTask = useCallback(async () => {
setIsAuthenticated(false);
}, []);
return (
<DailyTaskHookContext.Provider
value={{
startDailyTask,
stopDailyTask,
}}>
{children}
</DailyTaskHookContext.Provider>
);
};
export const useDailyTaskHook = () => useContext(DailyTaskHookContext);
how to implement BackgroundFetch.registerHeadlessTask(MyHeadlessTask);
See the API docs in the README enableHeadless
how to implement BackgroundFetch.registerHeadlessTask(MyHeadlessTask);
See the API docs in the README
enableHeadless
ah thanks recently noticed the headless part, in that case is this code correct https://github.com/transistorsoft/react-native-background-fetch/issues/445#issuecomment-1496110303
my app.js, its a complex project and i need it to start only after authenticated DailyTasksHook
const App = () => {
useEffect(() => {
const isHermes = () => !!global.HermesInternal;
console.log('Engine isHermes:', isHermes());
}, []);
return (
<Network.NetInfoContextProvider>
<AppUpdater.UpdaterContextProvider>
<DeepLink.DeepLinkProvider>
<Socket.SocketContextProvider>
<DailyTasksHook.DailyTaskContextProvider>
<Auth.GoogleAuthenticationHook.GoogleAuthenticationProvider>
<Auth.AuthenticationHook.AuthenticationProvider>
<AppError.ApiErrorContextProvider>
<Permiter.PermiterContextProvider>
<AppState.AppStateModeContextProvider>
<SharingIntent.ReceiveSharingIntentProvider>
<Nav.RootNavigator />
<FlashMessage
position={
Platform.OS === 'ios'
? 'top'
: {
top: StatusBar.currentHeight,
left: 0,
right: 0,
}
}
floating={Platform.OS !== 'ios'}
style={styles.flashMessage}
duration={3000}
/>
</SharingIntent.ReceiveSharingIntentProvider>
</AppState.AppStateModeContextProvider>
</Permiter.PermiterContextProvider>
</AppError.ApiErrorContextProvider>
</Auth.AuthenticationHook.AuthenticationProvider>
</Auth.GoogleAuthenticationHook.GoogleAuthenticationProvider>
</DailyTasksHook.DailyTaskContextProvider>
</Socket.SocketContextProvider>
</DeepLink.DeepLinkProvider>
</AppUpdater.UpdaterContextProvider>
</Network.NetInfoContextProvider>
);
};
Update:
Is this ok instead ?
index.js, i dont want to make it all messy inside index.js, is calling it this way ok ?
/**
* @format
*/
import './wdyr';
import './headlessTask';
import {AppRegistry} from 'react-native';
import {enableFreeze} from 'react-native-screens';
import App from './App';
import {name as appName} from './app.json';
// https://github.com/software-mansion/react-native-screens#readme
enableFreeze(true);
AppRegistry.registerComponent(appName, () => App);
headlessTask.js
import BackgroundFetch from 'react-native-background-fetch';
import {backgroundDataGetter} from './src/components/background/dailyUpdater/accountHelper';
const taskCallback = async taskId => {
console.log('Background fetch started');
await backgroundDataGetter(); // here i will check if current user is authenticated in localdb or still has access before calling server api
BackgroundFetch.finish(taskId);
console.log('Background fetch finished');
};
const onTimeout = async taskId => {
console.warn('[BackgroundFetch] TIMEOUT task: ', taskId);
BackgroundFetch.finish(taskId);
};
const synWithDb = () => {
BackgroundFetch.configure(
{
minimumFetchInterval: 15, // 15 minutes
stopOnTerminate: false,
enableHeadless: true,
forceAlarmManager: true,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY,
},
taskCallback,
onTimeout,
);
BackgroundFetch.start();
console.log('Background fetch initiated');
};
BackgroundFetch.registerHeadlessTask(synWithDb);
also update, in https://github.com/transistorsoft/react-native-background-fetch/tree/master/example i dont see anywhere config is being used how do i use the config options ?
update i found it https://github.com/transistorsoft/react-native-background-fetch/blob/master/example/App.tsx will update back after following the example properly
Headless-tasks are easily tested with simulated-tasks. Do not use forceAlarmManager: true
when simulating tasks.
update i followed through example, very explanative no idea how i missed it but i got some question.
if i dont call BackgroundFetch.scheduleTask()
no task seems to run or BackgroundFetch.configure()
callback does not execute, so do i need to call BackgroundFetch.scheduleTask()
with periodic: true
for it to always run ? and if so would it also be the one to make the task BackgroundFetch.registerHeadlessTask()
run when app is closed ?
if BackgroundFetch.scheduleTask()
is just an additional functionality if i call BackgroundFetch.configure()
at app.js in useEffect
will it run after 15 minutes?
i am asking cause no task running unless i call BackgroundFetch.scheduleTask()
BackgroundFetch.scheduleTask() is just an additional functionality
It is not required. .configure the plug-in without forceAlarmManager: true
, simulate a task as documented in the readme, observe $ adb logcat and post the logs here.
my bad forgot to call BackgroundFetch.start();
, all working well, took a while in debug mode but thats not an issue, i have one last question regarding BackgroundFetch.scheduleTask().
can BackgroundFetch.scheduleTask() be ran multiples time with different taskId ? if i set BackgroundFetch.scheduleTask() to run every 1 minute, if i close app will it still continue running or only runs when app open?
can BackgroundFetch.scheduleTask() be ran multiples time with different taskId ?
Yes.
if i set BackgroundFetch.scheduleTask() to run every 1 minute, if i close app will it still continue running or only runs when app open?
Why don’t you try it and see for yourself while observing $ adb logcat?
ah sure will try that later, will consider this solved thanks.
@abdullahIsa I just want to confirm, can i use this library for multiple api post call requests??
@abdullahIsa I just want to confirm, can i use this library for multiple api post call requests??
yes can, as long set well, i recommend just for calling apis and doing things like updating localdb, does its job well.
@abdullahIsa Okay thanks.
Your Environment
react-native -v
): 0.70.6Expected Behavior
It should run every 15 minutes on any android devices
Actual Behavior
Does not seem to work as i have a way to check when was last run and its always on default which is "pending..." instead of time of last run
Steps to Reproduce
Context
I am trying to run a task every 15 minutes, a simple function will get called that has api to call the server for latest data, basically syncing users local db with remote db.
Debug logs
include iOS / Android logs
Code
i got no idea what is wrong as no error or anything, am i missing something to add for release mode ? thanks.