mobile: enable experimental background sync

This commit is contained in:
Ammar Ahmed
2023-12-04 15:40:40 +05:00
committed by Abdullah Atta
parent 305a522a65
commit 9e8b5487b2
7 changed files with 140 additions and 102 deletions

View File

@@ -400,6 +400,14 @@ export const settingsGroups: SettingSection[] = [
type: "switch",
property: "disableSync"
},
{
id: "background-sync",
name: "Background sync (Experimental)",
description:
"Periodically wake up the app in background to sync your notes from other devices.",
type: "switch",
property: "backgroundSync"
},
{
id: "sync-issues-fix",
name: "Having problems with sync",

View File

@@ -21,6 +21,11 @@ import {
beginBackgroundTask,
endBackgroundTask
} from "react-native-begin-background-task";
import BackgroundFetch from "@ammarahmed/react-native-background-fetch";
import { DatabaseLogger, db } from "../common/database";
import { AppState, AppRegistry } from "react-native";
import Notifications from "./notifications";
import SettingsService from "./settings";
async function doInBackground(callback: () => Promise<void>) {
if (Platform.OS === "ios") {
@@ -45,107 +50,116 @@ async function doInBackground(callback: () => Promise<void>) {
}
}
// import BackgroundFetch from "react-native-background-fetch";
// import { DatabaseLogger, db } from "../common/database";
// import { AppState, AppRegistry } from "react-native";
// import Notifications from "./notifications";
// import SettingsService from "./settings";
let backgroundFetchStarted = false;
async function start() {
if (backgroundFetchStarted) return;
backgroundFetchStarted = true;
if (!SettingsService.getProperty("backgroundSync")) {
return;
}
// BackgroundFetch event handler.
const onEvent = async (taskId: string) => {
DatabaseLogger.info(
`BACKGROUND FETCH ON EVENT ${taskId}, ${AppState.currentState}}`
);
// Do your background work...
await onBackgroundSyncStarted();
// IMPORTANT: You must signal to the OS that your task is complete.
BackgroundFetch.finish(taskId);
};
// let backgroundFetchStarted = false;
// async function start() {
// if (backgroundFetchStarted) return;
// backgroundFetchStarted = true;
// // BackgroundFetch event handler.
// const onEvent = async (taskId: string) => {
// console.log("[BackgroundFetch] task: ", taskId, AppState.currentState);
// // Do your background work...
// await onBackgroundSyncStarted();
// // IMPORTANT: You must signal to the OS that your task is complete.
// BackgroundFetch.finish(taskId);
// };
// Timeout callback is executed when your Task has exceeded its allowed running-time.
// You must stop what you're doing immediately BackgroundFetch.finish(taskId)
const onTimeout = async (taskId: string) => {
DatabaseLogger.info(`BACKGROUND FETCH TIMEOUT: ${taskId}`);
BackgroundFetch.finish(taskId);
};
// // Timeout callback is executed when your Task has exceeded its allowed running-time.
// // You must stop what you're doing immediately BackgroundFetch.finish(taskId)
// const onTimeout = async (taskId: string) => {
// console.warn("[BackgroundFetch] TIMEOUT: ", taskId);
// BackgroundFetch.finish(taskId);
// };
// Initialize BackgroundFetch only once when component mounts.
const status = await BackgroundFetch.configure(
{
minimumFetchInterval: 15,
enableHeadless: true,
startOnBoot: true,
stopOnTerminate: false,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY
},
onEvent,
onTimeout
);
DatabaseLogger.info(`[BackgroundFetch] configure status: ${status}`);
}
// // Initialize BackgroundFetch only once when component mounts.
// const status = await BackgroundFetch.configure(
// {
// minimumFetchInterval: 15,
// enableHeadless: true,
// startOnBoot: true,
// stopOnTerminate: false,
// requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY
// },
// onEvent,
// onTimeout
// );
// DatabaseLogger.info(`[BackgroundFetch] configure status: ${status}`);
// console.log(`[BackgroundFetch] configure status: ${status}`);
// }
const task = async (event: { taskId: string; timeout: boolean }) => {
// Get task id from event {}:
const taskId = event.taskId;
const isTimeout = event.timeout; // <-- true when your background-time has expired.
if (isTimeout) {
console.log(`BACKGROUND FETCH TIMEOUT: ${taskId}`);
BackgroundFetch.finish(taskId);
return;
}
DatabaseLogger.info("BACKGROUND SYNC START" + taskId + AppState.currentState);
await onBackgroundSyncStarted();
BackgroundFetch.finish(taskId);
};
// const task = async (event: { taskId: string; timeout: boolean }) => {
// // Get task id from event {}:
// const taskId = event.taskId;
// const isTimeout = event.timeout; // <-- true when your background-time has expired.
// if (isTimeout) {
// console.log("[BackgroundFetch] Headless TIMEOUT:", taskId);
// BackgroundFetch.finish(taskId);
// return;
// }
// DatabaseLogger.info(
// "[BackgroundFetch HeadlessTask] start: " + taskId + AppState.currentState
// );
// await onBackgroundSyncStarted();
// BackgroundFetch.finish(taskId);
// };
BackgroundFetch.registerHeadlessTask(task);
// BackgroundFetch.registerHeadlessTask(task);
async function onBackgroundSyncStarted() {
try {
if (!db.isInitialized) {
await db.init();
} else {
await db.initCollections();
}
// async function onBackgroundSyncStarted() {
// try {
// DatabaseLogger.info("Background Sync" + "start");
// await db.init();
// const user = await db.user?.getUser();
// if (user) {
// await db.sync(true, false);
// }
// await Notifications.setupReminders();
// DatabaseLogger.info("Background Sync" + "end");
// } catch (e) {
// DatabaseLogger.error(e as Error);
// console.log("Background Sync Error", (e as Error).message);
// }
// }
const user = await db.user?.getUser();
if (user) {
await db.sync(true, false);
}
await Notifications.setupReminders();
DatabaseLogger.info("BACKGROUND SYNC COMPLETE");
} catch (e) {
DatabaseLogger.error(e as Error);
console.log("BACKGROUND SYNC ERROR", (e as Error).message);
}
}
// const onBoot = async () => {
// try {
// DatabaseLogger.info("BOOT TASK STARTED");
// await db.init();
// await Notifications.setupReminders();
// SettingsService.init();
// if (SettingsService.get().notifNotes) {
// Notifications.pinQuickNote(false);
// }
// DatabaseLogger.info("BOOT TASK COMPLETE");
// } catch (e) {
// console.log(e);
// }
// };
const onBoot = async () => {
try {
if (!SettingsService.getProperty("backgroundSync")) {
return;
}
// const registerHeadlessTask = () =>
// AppRegistry.registerHeadlessTask(
// "com.streetwriters.notesnook.BOOT_TASK",
// () => {
// return onBoot;
// }
// );
DatabaseLogger.info("BOOT TASK STARTED");
if (!db.isInitialized) {
await db.init();
} else {
await db.initCollections();
}
await Notifications.setupReminders();
SettingsService.init();
if (SettingsService.get().notifNotes) {
Notifications.pinQuickNote(false);
}
DatabaseLogger.info("BOOT TASK COMPLETE");
} catch (e) {
console.log(e);
}
};
const registerHeadlessTask = () =>
AppRegistry.registerHeadlessTask(
"com.streetwriters.notesnook.BOOT_TASK",
() => {
return onBoot;
}
);
export const BackgroundSync = {
start,
registerHeadlessTask
};
// export const BackgroundSync = {
// start,
// registerHeadlessTask
// };
export default { doInBackground };

View File

@@ -79,6 +79,7 @@ export type Settings = {
markdownShortcuts?: boolean;
appLockHasPasswordSecurity?: boolean;
biometricsAuthEnabled?: boolean;
backgroundSync?: boolean;
};
type DimensionsType = {

View File

@@ -161,12 +161,12 @@
android:resource="@xml/file_viewer_provider_paths" />
</provider>
<!-- <receiver android:exported="true" android:name=".BootRecieverService" >-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.BOOT_COMPLETED" />-->
<!-- <action android:name="android.intent.action.QUICKBOOT_POWERON" />-->
<!-- </intent-filter>-->
<!-- </receiver>-->
<receiver android:exported="true" android:name=".BootRecieverService" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
</application>

View File

@@ -9,6 +9,8 @@ import appJson from './app.json';
import Notifications from "../app/services/notifications";
import NetInfo from "@react-native-community/netinfo";
import { enableFreeze } from "react-native-screens";
import {BackgroundSync} from '../app/services/background-sync';
enableFreeze(true);
NetInfo.configure({
reachabilityUrl: "https://notesnook.com",
@@ -17,7 +19,7 @@ NetInfo.configure({
return response?.status >= 200 && response?.status < 300;
}
});
BackgroundSync.start();
Notifications.init();
const appName = appJson.name;

View File

@@ -64,7 +64,8 @@
"react-native-webview": "^11.14.1",
"react-native-zip-archive": "6.0.9",
"react-native-quick-sqlite": "^8.0.6",
"react-native-theme-switch-animation": "^0.6.0"
"react-native-theme-switch-animation": "^0.6.0",
"@ammarahmed/react-native-background-fetch": "^4.2.2"
},
"devDependencies": {
"@babel/core": "^7.20.0",

View File

@@ -27657,6 +27657,7 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@ammarahmed/notifee-react-native": "7.4.4",
"@ammarahmed/react-native-background-fetch": "^4.2.2",
"@ammarahmed/react-native-eventsource": "1.1.0",
"@ammarahmed/react-native-share-extension": "^2.5.5",
"@ammarahmed/react-native-sodium": "1.5.4",
@@ -27797,6 +27798,11 @@
"react-native": "*"
}
},
"node_modules/@ammarahmed/react-native-background-fetch": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-background-fetch/-/react-native-background-fetch-4.2.2.tgz",
"integrity": "sha512-PLBlb/DD+6Fv1auxdD6VRxtuC7GKPhQqR69bovRm5oGavbdSzRr+ZTr8AyNMCcayxKGdgEX2JysrJg8WIySSFQ=="
},
"node_modules/@ammarahmed/react-native-eventsource": {
"version": "1.1.0",
"license": "MIT",
@@ -47661,6 +47667,11 @@
"version": "7.4.4",
"requires": {}
},
"@ammarahmed/react-native-background-fetch": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@ammarahmed/react-native-background-fetch/-/react-native-background-fetch-4.2.2.tgz",
"integrity": "sha512-PLBlb/DD+6Fv1auxdD6VRxtuC7GKPhQqR69bovRm5oGavbdSzRr+ZTr8AyNMCcayxKGdgEX2JysrJg8WIySSFQ=="
},
"@ammarahmed/react-native-eventsource": {
"version": "1.1.0",
"requires": {}
@@ -80023,6 +80034,7 @@
"version": "file:native",
"requires": {
"@ammarahmed/notifee-react-native": "7.4.4",
"@ammarahmed/react-native-background-fetch": "^4.2.2",
"@ammarahmed/react-native-eventsource": "1.1.0",
"@ammarahmed/react-native-share-extension": "^2.5.5",
"@ammarahmed/react-native-sodium": "1.5.4",