【鸿蒙心迹】端云协同开发实战:让数据在端和云之间无缝流动
【鸿蒙心迹】端云协同开发实战:让数据在端和云之间无缝流动
摘要:本文系统讲解鸿蒙端云协同开发。先建立整体认知,说明 Cloud DB、Cloud Function、Cloud Storage 三件套的分工与适用边界;再拆解 Cloud DB 的"端云双写+自动同步"机制、数据模型配置要点与四种冲突解决策略;最后以端云协同笔记应用为例,完整走通 AGC 数据模型配置、端侧初始化、读写数据、同步策略与离线处理流程,并总结 schema 路径、字段类型、冲突覆盖、权限配置等常见坑的排查方法。
"端云协同"这个词在华为的文档里出现频率极高,但到底协同什么、怎么协同,文档里讲得云里雾里。我第一次做端云协同开发时,以为就是普通的"前端+后端"模式,后来才发现鸿蒙的端云协同是一套完整的体系——Cloud DB、Cloud Function、Cloud Storage,三个组件各有分工,配合端侧SDK实现数据的自动同步和离线可用。最让人头疼的是Cloud DB的数据模型配置,配错一个字段类型同步就报错,而且错误信息极其模糊。
如果你有鸿蒙应用开发基础,想让你的应用支持云端数据同步和离线可用,但对端云协同体系不熟悉,这篇正好适合你。读完后你会知道:端云协同的三件套各自的作用、Cloud DB的数据同步机制、完整的端云协同开发流程。
本文分三层来讲:第一层建立对端云协同的整体认知;第二层拆解Cloud DB的同步原理和配置方法;第三层是完整的实战落地和踩坑排错。
入门认知:端云协同到底"协"了什么
一句话定义
端云协同是鸿蒙提供的端云一体化开发能力——应用在端侧通过SDK直接读写云端数据,系统自动处理同步、冲突解决和离线缓存,开发者不需要自己搭建后端服务和同步逻辑。
打个比方:传统开发就像自己开快递公司——建仓库、雇快递员、规划路线、处理丢件;端云协同就像用顺丰——你只管把包裹交给顺丰,运输、仓储、配送全由他们处理,你只关心寄什么和收什么。
端云协同 vs 传统前后端
| 对比维度 | 传统前后端 | 端云协同 |
|---|---|---|
| 后端搭建 | 自己搭服务器+数据库 | 无需搭建,云端即服务 |
| 数据同步 | 自己写同步逻辑 | SDK自动同步 |
| 离线支持 | 自己实现本地缓存 | Cloud DB自动缓存 |
| 冲突解决 | 自己写冲突处理 | 系统自动解决 |
| 扩展性 | 自己扩容 | 云端自动扩容 |
表1:传统前后端与端云协同对比
全景图示
图2:端云协同三件套架构
三件套各自分工
| 组件 | 作用 | 类比 | 典型场景 |
|---|---|---|---|
| Cloud DB | 结构化数据存储与同步 | 数据库 | 用户数据、配置、记录 |
| Cloud Function | 云端业务逻辑执行 | 服务器API | 数据校验、聚合计算 |
| Cloud Storage | 文件存储 | 文件服务器 | 图片、视频、文档 |
表2:端云协同三件套分工
适用边界
端云协同适合:需要多端数据同步的应用、需要离线可用的应用、不想自建后端的轻量应用。不适合:需要高度定制化后端逻辑的复杂应用、对数据存储位置有严格合规要求的场景。
下面用一张决策图帮你快速判断自己的项目是否适合端云协同:
图1:端云协同适用性判断
进阶原理:Cloud DB的同步机制
Cloud DB的数据同步模型
Cloud DB的核心是"端云双写+自动同步":
图3:Cloud DB端云同步时序
数据模型配置
Cloud DB的数据模型在AGC(AppGallery Connect)控制台中配置,定义后导出schema文件供端侧使用:
| 配置项 | 说明 | 常见坑 |
|---|---|---|
| 对象类型名 | 数据表名 | 必须和端侧代码一致 |
| 字段名 | 属性名 | 大小写敏感 |
| 字段类型 | 数据类型 | 端侧类型必须匹配 |
| 主键 | 唯一标识 | 必须有一个主键 |
| 索引 | 查询优化字段 | 常用查询字段建索引 |
| 权限 | 读写权限控制 | 默认只有创建者可读写 |
表3:Cloud DB数据模型配置项
[注意] 字段类型一旦配置并发布,就不能修改!如果需要改字段类型,只能创建新的对象类型。这是最大的坑之一。
同步冲突解决策略
当端侧和云端同时修改同一条数据时,冲突如何解决?
| 策略 | 含义 | 适用场景 |
|---|---|---|
| 云端优先 | 云端数据覆盖端侧 | 需要服务端权威的场景 |
| 端侧优先 | 端侧数据覆盖云端 | 离线编辑优先的场景 |
| 时间戳优先 | 最后修改的为准 | 大多数通用场景 |
| 自定义 | 开发者自定义逻辑 | 需要业务逻辑判断 |
表4:冲突解决策略
冲突解决的整体判断流程如下:
图4:同步冲突解决流程
常见误区
误区1:把Cloud DB当普通数据库用
Cloud DB不是关系型数据库,不支持JOIN、复杂查询。它是面向移动端的轻量级同步数据库,查询能力有限。复杂查询应该用Cloud Function在云端处理。
误区2:不配置权限就用
默认权限是"只有创建者可读写",意味着用户A的数据用户B完全看不到。如果需要数据共享(比如团队协作),必须在AGC控制台配置权限规则。
高级应用:从零实现一个端云协同笔记应用
实战步骤
第一步:在AGC控制台配置数据模型
在AppGallery Connect中创建Cloud DB数据模型:
{
"objectTypeName": "Note",
"fields": [
{ "fieldName": "id", "fieldType": "String", "isPrimaryKey": true },
{ "fieldName": "title", "fieldType": "String", "isNullable": false },
{ "fieldName": "content", "fieldType": "String", "isNullable": true },
{ "fieldName": "createTime", "fieldType": "Date", "isNullable": false },
{ "fieldName": "updateTime", "fieldType": "Date", "isNullable": false },
{ "fieldName": "userId", "fieldType": "String", "isNullable": false }
],
"indexes": [
{ "indexName": "userId_index", "indexList": ["userId"] }
],
"permissions": [
{ "role": "Creator", "read": true, "write": true },
{ "role": "AllUsers", "read": false, "write": false }
]
}
导出schema文件后放到端侧项目的 resources/rawfile 目录下。
第二步:端侧初始化Cloud DB
import { cloudDatabase } from '@kit.CloudFoundationKit'
let cloudDB: cloudDatabase.CloudDB
let noteZone: cloudDatabase.CloudDBZone
async function initCloudDB(): Promise<void> {
// 1. 初始化Cloud DB
let config = new cloudDatabase.CloudDBZoneConfig({
zoneName: 'NoteZone',
schemaUrl: 'resources/rawfile/NoteSchema.json'
})
// 2. 打开Zone
cloudDB = await cloudDatabase.openCloudDBZone(config)
// 3. 注册同步监听
cloudDB.on('dataChange', (change) => {
// 云端数据变更通知
if (change.type === cloudDatabase.ChangeType.UPSERT) {
this.onNoteUpserted(change.data)
} else if (change.type === cloudDatabase.ChangeType.DELETE) {
this.onNoteDeleted(change.data)
}
})
}
第三步:端侧读写数据
// 插入笔记
async function addNote(title: string, content: string): Promise<void> {
let note: Note = {
id: generateUUID(),
title: title,
content: content,
createTime: new Date(),
updateTime: new Date(),
userId: getCurrentUserId()
}
await cloudDB.upsert(note)
// upsert会自动触发同步到云端
}
// 查询笔记
async function queryNotes(): Promise<Note[]> {
let condition = new cloudDatabase.CloudDBZoneQuery(Note)
.equalTo('userId', getCurrentUserId())
.orderByDesc('updateTime')
let result = await cloudDB.query(condition)
return result.snapshotObjects
}
// 更新笔记
async function updateNote(note: Note): Promise<void> {
note.updateTime = new Date()
await cloudDB.upsert(note)
// 自动同步更新到云端
}
// 删除笔记
async function deleteNote(noteId: string): Promise<void> {
let condition = new cloudDatabase.CloudDBZoneQuery(Note)
.equalTo('id', noteId)
await cloudDB.delete(condition)
}
第四步:配置同步策略
// 设置同步策略
let syncConfig: cloudDatabase.SyncConfig = {
mode: cloudDatabase.SyncMode.CLOUD_SYNC_MODE_AUTO,
conflictPolicy: cloudDatabase.ConflictPolicy.CLOUD_DB_CONFLICT_POLICY_TIMESTAMP
}
cloudDB.setSyncConfig(syncConfig)
同步模式说明:
AUTO:自动同步,网络可用时实时同步MANUAL:手动同步,需要显式调用sync方法LOCAL_ONLY:只本地存储,不同步到云端
第五步:离线处理
// 网络状态监听
import { connection } from '@kit.NetworkKit'
connection.createNetConnection().on('netAvailable', () => {
// 网络恢复,触发同步
cloudDB.sync(cloudDatabase.SyncMode.CLOUD_SYNC_MODE_AUTO)
})
connection.createNetConnection().on('netLost', () => {
// 网络断开,切换为离线模式
// Cloud DB自动使用本地缓存,读写不受影响
})
整个笔记应用的端云协同数据流如下:
图5:笔记应用端云协同数据流
踩坑排错
坑1:schema文件路径不对
现象:初始化Cloud DB时报 “schema not found” 错误。
原因:schema文件路径配置错误。schemaUrl 是相对于项目根目录的路径,不是相对于代码文件的路径。
解决:把schema文件放到 resources/rawfile/ 目录下,路径写 resources/rawfile/NoteSchema.json。
坑2:字段类型不匹配
现象:upsert数据时报 “type mismatch” 错误。
原因:端侧代码中的字段类型和AGC控制台配置的类型不一致。比如控制台配的是 Integer,端侧代码用了 number(JavaScript的number是浮点型)。
解决:严格对照schema配置端侧字段类型。Date类型在端侧必须用 Date 对象,不能传时间戳数字。
坑3:同步冲突导致数据丢失
现象:两台设备同时编辑同一条笔记,后同步的覆盖了先同步的修改。
原因:默认冲突策略是"云端优先",后同步到云端的数据会覆盖先同步的。
解决:改为"时间戳优先"策略,以最后修改时间为准:
let syncConfig: cloudDatabase.SyncConfig = {
mode: cloudDatabase.SyncMode.CLOUD_SYNC_MODE_AUTO,
conflictPolicy: cloudDatabase.ConflictPolicy.CLOUD_DB_CONFLICT_POLICY_TIMESTAMP
}
坑4:权限配置导致数据不可见
现象:用户A创建的笔记,用户B登录后查不到。
原因:默认权限是"只有创建者可读写",其他用户看不到。
解决:在AGC控制台修改权限规则,或者用Cloud Function做数据分发。
最佳实践
- schema文件放rawfile:路径固定为
resources/rawfile/,避免找不到文件 - 字段类型严格匹配:端侧类型必须和云端配置完全一致
- 冲突策略选时间戳:大多数场景用时间戳优先最合理
- 离线模式要测试:断网后读写、恢复后同步,必须完整测试
- 权限规则提前规划:默认只有创建者可读写,团队协作需要提前改权限
遇到问题时,可以按下面的排查路径逐项定位:
图6:常见问题排查路径
总结
核心要点:
- 端云协同三件套:Cloud DB(数据同步)、Cloud Function(云端逻辑)、Cloud Storage(文件存储)
- Cloud DB的核心是"端云双写+自动同步",端侧写入立即返回,后台自动同步到云端
- 数据模型在AGC控制台配置,字段类型一旦发布不可修改
- 冲突解决策略有四种,大多数场景用时间戳优先最合理
最佳实践清单:
- schema文件放 resources/rawfile/ 目录,路径不要写错
- 端侧字段类型必须和云端配置严格一致
- 冲突策略选时间戳优先,避免数据被意外覆盖
- 离线模式必须完整测试:断网读写→恢复同步→冲突处理
- 权限规则提前规划,默认只有创建者可读写
你在端云协同开发中遇到过什么坑?评论区聊聊。
更多推荐
所有评论(0)