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", type: "switch",
property: "disableSync" 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", id: "sync-issues-fix",
name: "Having problems with sync", name: "Having problems with sync",

View File

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

View File

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

View File

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

View File

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

View File

@@ -64,7 +64,8 @@
"react-native-webview": "^11.14.1", "react-native-webview": "^11.14.1",
"react-native-zip-archive": "6.0.9", "react-native-zip-archive": "6.0.9",
"react-native-quick-sqlite": "^8.0.6", "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": { "devDependencies": {
"@babel/core": "^7.20.0", "@babel/core": "^7.20.0",

View File

@@ -27657,6 +27657,7 @@
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {
"@ammarahmed/notifee-react-native": "7.4.4", "@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-eventsource": "1.1.0",
"@ammarahmed/react-native-share-extension": "^2.5.5", "@ammarahmed/react-native-share-extension": "^2.5.5",
"@ammarahmed/react-native-sodium": "1.5.4", "@ammarahmed/react-native-sodium": "1.5.4",
@@ -27797,6 +27798,11 @@
"react-native": "*" "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": { "node_modules/@ammarahmed/react-native-eventsource": {
"version": "1.1.0", "version": "1.1.0",
"license": "MIT", "license": "MIT",
@@ -47661,6 +47667,11 @@
"version": "7.4.4", "version": "7.4.4",
"requires": {} "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": { "@ammarahmed/react-native-eventsource": {
"version": "1.1.0", "version": "1.1.0",
"requires": {} "requires": {}
@@ -80023,6 +80034,7 @@
"version": "file:native", "version": "file:native",
"requires": { "requires": {
"@ammarahmed/notifee-react-native": "7.4.4", "@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-eventsource": "1.1.0",
"@ammarahmed/react-native-share-extension": "^2.5.5", "@ammarahmed/react-native-share-extension": "^2.5.5",
"@ammarahmed/react-native-sodium": "1.5.4", "@ammarahmed/react-native-sodium": "1.5.4",