如何使用西瓜传递同步功能的数据



大家好,我正在使用西瓜,我有下面的代码,但我不知道如何实际使用它。我是新的西瓜,我不知道如何将数据作为道具传递给pullChangespushChanges对象。如何传递必要的数据,如changeslastpullleat当我调用同步函数时,将从数据库导入同步函数。我也需要更多关于migrationsEnabledAtVersion: 1的解释。提前感谢您亲切的回答。

import { synchronize } from '@nozbe/watermelondb/sync'
async function mySync() {
await synchronize({
database,
pullChanges: async ({ lastPulledAt, schemaVersion, migration }) => {
const urlParams = `last_pulled_at=${lastPulledAt}&schema_version=${schemaVersion}&migration=${encodeURIComponent(JSON.stringify(migration))}`
const response = await fetch(`https://my.backend/sync?${urlParams}`)
if (!response.ok) {
throw new Error(await response.text())
}
const { changes, timestamp } = await response.json()
return { changes, timestamp }
},
pushChanges: async ({ changes, lastPulledAt }) => {
const response = await fetch(`https://my.backend/sync?last_pulled_at=${lastPulledAt}`, {
method: 'POST',
body: JSON.stringify(changes)
})
if (!response.ok) {
throw new Error(await response.text())
}
},
migrationsEnabledAtVersion: 1,
})
}

Watermelondb的文档很糟糕,它的typescript链接更糟糕。我花了将近一周的时间与一个简单的表实现100%的同步,现在我有同样的问题来解决与关联的同步。那么,您需要在pullChanges中返回的对象是以下形式的:

return {
changes: {
//person is the name of the table in the models
person: {
created: [
{
// in created you need to send null in the id, if you don't send the id it doesn't work
id: null,
// other fields of your schema, not model
}
],
updated: [
{
// the fields of your schema, not model
}
],
deleted: [
// is a string[] consisting of the watermelondb id of the records that were deleted in the remote database
],
}
},
timestamp: new Date().getTime() / 1000
}

在我的例子中,远程数据库不是西瓜数据库,而是mySQL,并且我的API中没有端点以西瓜格式返回所有内容。对于每个表,我使用deletedAt, updatedAt或createdAt>并进行必要的过滤和准备,以便来自远程数据库的数据采用本地数据库的模式格式。

在pushChanges中,我通过为每个表调用适当的创建、更新或删除端点来执行相反的数据准备过程。

这是昂贵的和恼人的,但最终它工作得很好,最大的问题是西瓜的文档,这是可怕的。

export async function sync(id: Number, callback: (success: boolean) => void) {
const user_id = id;
const lastPulledAtTime = await AsyncStorage.getItem('LAST_SYNC_TIME')
synchronize({
database,
pullChanges: async ({ lastPulledAt }) => {
const response = await fetch(SYNC_API_URL_PULL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${BEARER_TOKEN}`,
},
body: JSON.stringify({ lastPulledAtTime, user_id }),
});
if (!response.ok) {
throw new Error(await response.text());
}
const { changes, timestamp } = await response.json();
return { changes, timestamp };
},
pushChanges: async ({ changes, lastPulledAt }) => {
try {
const formattedChanges = {
persons: {
created: [],
updated: [],
deleted: [],
},
contacts: {
created: [],
updated: [],
deleted: [],
},
};

const hasChanges = await hasUnsyncedChanges({ database });
if (hasChanges) {
const persons = await database.get('persons').query(Q.where('_status', 'updated'));
const contacts = await database.get('contacts').query(Q.where('_status', 'updated'));

persons.forEach(serializedRecord => {
const { _status, id, ...fields } = serializedRecord._raw;

if (_status === 'updated') {
const updatedFields = {
firstName: fields.first_name,
lastName: fields.last_name,
country: fields.country,
subdivision: fields.subdivision,
city: fields.city,
gender: fields.gender,
};
formattedChanges.persons.updated.push(updatedFields);
}
});

contacts.forEach(serializedRecord => {
const { _status, id, ...fields } = serializedRecord._raw;

if (_status === 'updated') {
const updatedFields = {
channel: fields.channel,
description: fields.description,
data: fields.data,
};
formattedChanges.contacts.updated.push(updatedFields);
}
});
}
const response = await fetch(`${SYNC_API_URL_PUSH}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${BEARER_TOKEN}`,
},
body: JSON.stringify({ changes: formattedChanges, user_id }),
});

if (!response.ok) {
throw new Error(await response.text());
}

callback(true); // Synchronization succeeded
} catch (error) {
console.error('Error pushing changes:', error.message);
callback(false); // Synchronization failed
}
},


}).catch((error) => {
console.error('Error syncing:', error.message);
callback(false); // Synchronization failed
});
}

就是这样做的:查看是否有任何不同步的更改,提取更改的字段并将其格式化以适应您的后端。不是最理想的,但这是一个开始

最新更新