在离线Meteor/React本机应用程序中重复

在离线Meteor/React本机应用程序中重复,meteor,react-native,redux,Meteor,React Native,Redux,我通常会在Google/Stackoverflow/Meteor论坛上找到问题的解决方案,或者找人来解决。然而,这次我完全被卡住了。这是我的问题: 我已经用Meteor/React/React Native创建了一个现场服务管理应用程序。经理可以在web应用程序上创建任务/工作单,现场团队可以在移动应用程序上创建报告/工作日志 然而,我所在的地区在某些地区的互联网连接很差。因此,脱机功能对于查看任务/报告以及创建报告(而不是任务)都至关重要。为了解决离线数据访问问题,我遵循了Spencer Ca

我通常会在Google/Stackoverflow/Meteor论坛上找到问题的解决方案,或者找人来解决。然而,这次我完全被卡住了。这是我的问题:

我已经用Meteor/React/React Native创建了一个现场服务管理应用程序。经理可以在web应用程序上创建任务/工作单,现场团队可以在移动应用程序上创建报告/工作日志

然而,我所在的地区在某些地区的互联网连接很差。因此,脱机功能对于查看任务/报告以及创建报告(而不是任务)都至关重要。为了解决离线数据访问问题,我遵循了Spencer Carli的优秀教程

它工作得很好

创建脱机报告时出错。基本上,我在redux应用商店中创建了一个操作队列来处理脱机报告的创建。当连接重新联机时,将映射操作,在服务器上创建报告,然后删除操作,并从mini mongo和redux中删除脱机创建的报告,因为无论如何,一旦在服务器上创建,它将再次自动同步

它工作得很好,但有时,特别是当互联网连接很慢时,会创建副本。比如,同一份报告有时会有50多份副本

以下是操作队列同步:

异步handleSync(props){
const data=Meteor.getData();
const db=data&&data.db;
if(props.loading==false&&props.connectionStatus=='connected'&&Meteor.userId()&&db&&props.actionQueue&&props.actionQueue.length>0){
for(让道具的动作。动作队列){
如果(action.msg=='createReport'){
常数报告={
organizationId:action.doc.organizationId,
taskId:action.doc.taskId,
状态:action.doc.status,
startedAt:action.doc.startedAt,
};
const result=wait Meteor.call('Reports.create',report,(error,res)=>{
如果(错误){
Alert.Alert(I18n.t('main.error'),`${I18n.t('main.errorSyncReport')}${error.reason}`);
}否则{
分派({type:'REMOVE_ACTION_QUEUE',payload:ACTION.actionId});
分派({type:'REMOVE\u OFFLINE\u REPORT',负载:action.doc.\u id});
db['reports'].del(action.doc.\u id);
常量任务={
organizationId:action.doc.organizationId,
taskId:action.doc.taskId,
};
Meteor.call('Tasks.updateTaskStatus',task);
}
});
返回结果;
} 
else if(action.msg==='completeReport'){
//此操作用于完成在线创建的报告
常数报告={
organizationId:action.doc.organizationId,
reportId:action.doc.\u id,
注释:action.doc.comments,
isTaskCompleted:action.doc.isTaskCompleted,
completedAt:action.doc.completedAt,
字段:action.doc.fields,
};
const result=wait Meteor.call('Reports.completeReport',report,(error,res)=>{
如果(错误){
Alert.Alert(I18n.t('main.error'),`${I18n.t('main.errorSyncReport')}${error.reason}`);
}否则{
分派({type:'REMOVE_ACTION_QUEUE',payload:ACTION.actionId});
常量任务={
organizationId:action.doc.organizationId,
taskId:action.doc.taskId,
};
Meteor.call('Tasks.updateTaskStatus',task);
}
});
返回结果;
}
else if(action.msg==='createCompletedReport'){
//此操作用于完成脱机创建的报告,以避免id问题
//因此,将创建新的已完成报告并删除脱机报告
常数报告={
organizationId:action.doc.organizationId,
taskId:action.doc.taskId,
注释:action.doc.comments,
isTaskCompleted:action.doc.isTaskCompleted,
字段:action.doc.fields,
状态:action.doc.status,
startedAt:action.doc.startedAt,
completedAt:action.doc.completedAt,
};
const result=wait Meteor.call('Reports.create',report,(error,res)=>{
如果(错误){
Alert.Alert(I18n.t('main.error'),`${I18n.t('main.errorSyncReport')}${error.reason}`);
}否则{
分派({type:'REMOVE_ACTION_QUEUE',payload:ACTION.actionId});
分派({type:'REMOVE\u OFFLINE\u REPORT',负载:action.doc.\u id});
db['reports'].del(action.doc.\u id);
常量任务={
organizationId:action.doc.organizationId,
taskId:action.doc.taskId,
};
Meteor.call('Tasks.updateTaskStatus',task);
}
});
返回结果;
}
}
}
}
以下是基于Spencer教程的离线初始化:

const onRehydration=(存储)=>{
const data=Meteor.getData();
const db=data&&data.db;
中频(db){
_.each(store.getState(),(collectionData,collectionName)=>{
如果(collectionName!=='offlineUser'&&collectionName!=='offlineOrg'&&collectionName!=='actionQueue'&&collectionName!=='clipboard'){
如果(!db[collectionName]){
db.addCollection(collectionName);
}
const collectionar=u.map(collectionData,(doc,_id)=>{
文件id=\u id;
退货单;
});
db[collectionName].upsert(collectionar);
}
});
}
dispatch({type:'CACHING',CACHING:false})
};
导出常量initializeOffline=(opts={})=>{
设debug=false;
const logger=createLogger({谓词:()=>d