React Native应用实现后台日历同步的可行性及问题求助
React Native应用实现后台日历同步的可行性及问题求助
我已经在我的React Native应用里卡了好几个星期的一个功能了,先跟大家说下我的项目情况:
我做的是一个支持多用户协作的RN应用,用户1创建会议这类事件后,用户2会收到通知,同时用户1的本地日历会自动添加这个事件——现在我想实现的是,用户2的本地日历也能自动同步这个事件,哪怕用户2没打开App,在后台状态下也能完成同步。
尝试方案1:通过Firebase通知触发后台同步(已暂时放弃)
我首先想到的最优方案是利用通知:用户1创建会议时,用户2一定会收到通知,我想在通知展示的同时触发日历同步。我用的是Firebase推送,通知在后台能正常显示,但对应的同步代码就是不执行,还报了个错误:运行了多个ID为ReactNativeFirebaseMessagingHeadlessTask的HeadlessTask。虽然后台通知能正常接收,但console.log的内容完全打不出来,折腾了半天没解决,暂时放弃这个思路了。
以下是我注册后台通知的代码:
import * as React from 'react'; import { useState, useEffect } from 'react'; import { API_KEY, PROJECT_ID, STORAGE_BUCKET, MESSAGING_SENDER_ID, APP_ID } from '@env'; import firebase from '@react-native-firebase/app'; import messaging from '@react-native-firebase/messaging'; import { AppRegistry } from 'react-native'; import { syncCalendarEventId } from '../utils/calendarSync'; const register = async () => { const firebaseConfig = { apiKey: `${API_KEY}`, projectId: `${PROJECT_ID}`, storageBucket: `${STORAGE_BUCKET}`, messagingSenderId: `${MESSAGING_SENDER_ID}`, appId: `${APP_ID}`, // databaseURL: '...', // authDomain: '...', }; firebase .initializeApp(firebaseConfig) .then(() => { registerBackgroundMessage(); }) .catch(error => { }); }; export async function initializeNotifications() { await register(); if (!firebase.apps.length) { register(); } else { registerBackgroundMessage(); } } // 请求用户通知权限 export async function requestUserPermission() { const authStatus = await messaging().requestPermission(); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { const token = await messaging().getToken(); return token; } } // 注册后台消息处理器 const registerBackgroundMessage = () => { console.log("bg") if(Platform.OS === 'ios'){ messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Notification reçue en fond ! : ', remoteMessage); if(remoteMessage.data && remoteMessage.data.sync_required == 1){ syncCalendarEventId(); } }); } else if(Platform.OS === 'android'){ const headlessNotificationHandler = async (remoteMessage) => { console.log('Notification reçue en fond ! : ', remoteMessage); // 在这里添加你想在后台处理的逻辑 }; // 注册Headless任务 AppRegistry.registerHeadlessTask( 'ReactNativeFirebaseMessagingHeadlessTask', () => headlessNotificationHandler ); } };
尝试方案2:用react-native-background-fetch定时同步(未生效)
无奈之下我想到了次优方案——定时同步,比如每30分钟或1小时触发一次日历同步。我用了react-native-background-fetch库,但还是没效果,等了20、25分钟代码都没执行。相关代码写在App.js的useEffect里:
useEffect(() => { const configureBackgroundFetch = async () => { console.log("configure bg"); BackgroundFetch.configure( { minimumFetchInterval: 15, stopOnTerminate: false, startOnBoot: true, }, async (taskId) => { console.log("sync") syncCalendarEventId(); console.log(`Tâche de fetch avec ID ${taskId} exécutée`); BackgroundFetch.finish(taskId); }, (error) => { console.error('Erreur de configuration BackgroundFetch:', error); } ); console.log("fetch start"); BackgroundFetch.start(); console.log("fetch started"); }; configureBackgroundFetch(); }, []);
关于这个库的配置我应该是做对了:
- 在Xcode里已经勾选了
background fetch、background processing和background notifications选项 - 也更新了Info.plist文件:
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> <string>fetch</string> <string>processing</string> </array>
我的疑问
现在我就想请教大家:有没有办法实现在后台状态下自动同步日历的功能?还是说我只能放弃,只做用户打开App时的同步?
麻烦各位大佬帮忙看看了🙏
备注:内容来源于stack exchange,提问作者Emilien Charpié
相关产品推荐
相关产品推荐

