HarmonyOS End-Cloud Integration: Migrating a Standalone App to Cloud-Enabled Architecture
This tutorial walks through upgrading a HarmonyOS health app from local-only storage to an end-cloud integrated architecture using AppGallery Connect, covering architecture design, data synchronization strategies, CloudDB modeling, SDK initialization, and development environment setup with DevEco Studio and Node.js cloud functions.
What Is End-Cloud Integration
End-cloud integration (端云一体化) is a HarmonyOS solution that connects the device side with cloud services via AppGallery Connect (AGC), enabling automatic data synchronization across devices. The article contrasts this with traditional standalone apps where data resides only in local SQLite or RDB databases, leading to four key problems:
Data loss : Reinstalling the app or switching phones wipes all data.
No multi-device sync : Records entered on a phone are invisible on a tablet or watch.
Limited features : Cannot implement leaderboards, social interactions, or cloud-based AI analysis.
Manual backup burden : Users must export JSON files manually, which is error-prone and often forgotten.
End-Cloud Architecture
The architecture diagram shows the device side (ArkUI, business logic, local RDB) communicating over HTTPS with AGC cloud services:
┌─────────────────┐ ┌─────────────────────────────┐
│ HarmonyOS App │ ←────→ │ AppGallery Connect │
│ ┌───────────┐ │ HTTPS │ ┌─────────────────────┐ │
│ │ ArkUI │ │ │ │ Cloud Functions │ │
│ └───────────┘ │ │ │ (Node.js) │ │
│ ┌───────────┐ │ │ └─────────────────────┘ │
│ │ Business │ │ │ ┌─────────────────────┐ │
│ │ Logic │ │ │ │ CloudDB │ │
│ └───────────┘ │ │ └─────────────────────┘ │
│ ┌───────────┐ │ │ ┌─────────────────────┐ │
│ │ Local DB │ │ │ │ Cloud Storage │ │
│ │ (SQLite/ │ │ │ └─────────────────────┘ │
│ │ RDB) │ │ │ ┌─────────────────────┐ │
│ └───────────┘ │ │ │ Push Kit │ │
└─────────────────┘ │ └─────────────────────┘ │
└─────────────────────────────┘Benefits include automatic cloud backup, real-time multi-device sync, ready-to-use cloud capabilities (push, auth, AI), and pay-as-you-go pricing without managing servers.
Case Study: LightMeal (轻食刻) App Migration
The article uses a health-management app called LightMeal to illustrate the before/after comparison:
Fasting Logs : Standalone = Local only; End-Cloud = Cloud sync, visible on all devices
Weight Records : Standalone = Simple local charts; End-Cloud = Long-term trend analysis in cloud
Water Tracking : Standalone = Today only; End-Cloud = History stats + smart reminders
Exercise Records : Standalone = Personal only; End-Cloud = Leaderboards + friend interaction
Health Reports : Standalone = Generated locally; End-Cloud = Cloud AI analysis + sharing
Data Backup : Standalone = Manual JSON export; End-Cloud = Auto sync, one-tap restore
Technical Stack
Device Side (ArkTS/ArkUI)
// Core dependencies
import cloud from '@hw-agconnect/cloud'; // AGC Cloud SDK
import { authentication } from '@kit.AccountKit'; // Huawei Account auth
import { pushService } from '@kit.PushKit'; // Push service
import relationalStore from '@ohos.data.relationalStore'; // Local RDBRecommended project structure:
entry/src/main/ets/
├── pages/ # UI layer
├── components/ # Reusable components
├── services/ # Business services
│ ├── AuthService.ets
│ ├── SyncService.ets
│ └── PushService.ets
├── database/ # Data access layer
│ ├── DatabaseManager.ets
│ └── FastingDao.ets
└── model/ # Data models
├── FastingModels.ets
└── SyncModels.etsCloud Side (Node.js 18+, TypeScript)
CloudProgram/
├── cloudfunctions/ # Cloud functions
│ ├── huawei-auth/ # Huawei account auth
│ ├── data-sync-upload/ # Data upload sync
│ ├── data-sync-download/ # Data download sync
│ └── sync-meta/ # Sync metadata
├── clouddb/ # CloudDB object type definitions
│ └── objecttype/
└── cloud-config.json # Cloud development configCloudDB is a document-oriented database provided by AGC.
Data Flow and Synchronization Strategies
Data flows from UI → Business Service → Local DAO → Cloud Function API (HTTPS) → AGC CloudDB using incremental sync:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Device UI │←→ │Business Svc │←→ │ Local DAO │
└─────────────┘ └─────────────┘ └──────┬──────┘
│
┌─────────────┐
│ Cloud Func │ ←──── Incremental sync
│ API │
└──────┬──────┘
│
┌──────┴──────┐
│ AGC CloudDB │
└─────────────┘Four synchronization strategies are defined:
Full sync on login : Compare cloud and local data, merge intelligently.
Incremental sync on write : Immediately sync new records (e.g., a fasting entry) to cloud.
Scheduled background sync : Daily consistency check.
Conflict resolution : Timestamp-based last-write-wins for concurrent edits.
Development Environment Setup
DevEco Studio 5.0.0+ — HarmonyOS IDE
HarmonyOS SDK API 12+ — Supports end-cloud APIs
Node.js 18.x — Cloud function development
AGC Account Real-name verified — Huawei developer account
AGC Project Creation Steps
Log in to
https://developer.huawei.com/consumer/cn/service/josp/agc/index.htmlCreate project named "LightMeal End-Cloud"
Add HarmonyOS app with package name com.xxxx.health, download agconnect-services.json In DevEco Studio: install CloudDev plugin ( Settings → Plugins → CloudDev), log in to AGC, associate project, place agconnect-services.json at
Application/entry/src/main/resources/rawfile/agconnect-services.jsonProject Migration Preparation
Existing Local Database Analysis
The current DatabaseManager.ets uses RDB with fastone.db version 5:
export class DatabaseManager {
private store: relationalStore.RdbStore | null = null;
private readonly DATABASE_NAME = 'fastone.db';
private readonly DATABASE_VERSION = 5;
init(context: common.UIAbilityContext): Promise<void> {
const config: relationalStore.StoreConfig = {
name: this.DATABASE_NAME,
securityLevel: relationalStore.SecurityLevel.S1,
encrypt: false
};
// Initialize RDB...
}
}Seven tables require cloud sync:
fasting_logs — Fasting records — Sync: Yes
weight_records — Weight records — Sync: Yes
water_records — Water intake records — Sync: Yes
exercise_records — Exercise records — Sync: Yes
settings — App settings — Sync: Yes
health_reports — Health reports — Sync: Yes
daily_life_records — Daily life records — Sync: Yes
Adding End-Cloud Dependencies
In Application/entry/oh-package.json5:
{
"dependencies": {
"@hw-agconnect/cloud": "^1.0.0",
"@hw-agconnect/hmcore": "^1.0.0"
}
}Run cd Application/entry && ohpm install.
Initializing Cloud SDK
In EntryAbility.ets:
import { UIAbility, Want, AbilityConstant } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
import cloud from '@hw-agconnect/cloud';
export default class EntryAbility extends UIAbility {
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
try {
await cloud.initialize(this.context);
console.info('AGC Cloud SDK initialized successfully');
} catch (error) {
console.error('AGC Cloud SDK initialization failed:', error);
}
}
// ...
}Creating Cloud Development Directory Structure
mkdir -p CloudProgram/cloudfunctions
mkdir -p CloudProgram/clouddb/objecttypeCreate CloudProgram/cloud-config.json:
{
"cloudfunction": {
"runtime": "nodejs18",
"region": "cn-north-4"
},
"clouddb": {
"zoneName": "fastone"
}
}Data Model Design
Local Model (RDB Table)
// model/FastingModels.ets
export interface FastingRecord {
id: number; // Local auto-increment ID
startTime: number; // Start timestamp
endTime: number; // End timestamp
duration: number; // Duration in minutes
status: number; // 0: in-progress, 1: completed
createdAt: number; // Creation time
updatedAt: number; // Update time
}Cloud Model (CloudDB Object Type)
// CloudProgram/clouddb/objecttype/FastingLog.json
{
"objectTypeName": "FastingLog",
"fields": [
{ "fieldName": "id", "fieldType": "String", "isPrimaryKey": true },
{ "fieldName": "userId", "fieldType": "String", "notNull": true },
{ "fieldName": "localId", "fieldType": "Integer" },
{ "fieldName": "startTime", "fieldType": "Long", "notNull": true },
{ "fieldName": "endTime", "fieldType": "Long" },
{ "fieldName": "duration", "fieldType": "Integer" },
{ "fieldName": "status", "fieldType": "Integer", "defaultValue": "0" },
{ "fieldName": "createdAt", "fieldType": "DateTime" },
{ "fieldName": "updatedAt", "fieldType": "DateTime" }
]
}Model Mapping
┌─────────────────┐ ┌─────────────────┐
│ Local RDB Model│ │ Cloud CloudDB │
├─────────────────┤ ├─────────────────┤
│ id: number │ ──────→ │ id: string │ UUID generated
│ │ │ userId: string │ User association
│ startTime │ ←─────→ │ startTime │ Field mapping
│ endTime │ ←─────→ │ endTime │
│ duration │ ←─────→ │ duration │
│ status │ ←─────→ │ status │
│ createdAt │ ←─────→ │ createdAt │
│ updatedAt │ ←─────→ │ updatedAt │
└─────────────────┘ └─────────────────┘CloudDB object types are created in the AGC console via
Cloud Database → Object Types → Import → Select FastingLog.json.
Summary
Core value : Data persistence, multi-device sync, enhanced capabilities.
Architecture : Device (ArkTS + ArkUI + RDB) + Cloud (Cloud Functions + CloudDB).
Development flow : AGC project creation → Environment config → SDK integration → Data modeling.
Migration strategy : Retain local database, add cloud sync layer.
Next chapter will cover cloud function development and invocation, including creating the first cloud function, device-side invocation, Huawei account authentication flow, and cloud function debugging techniques.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
51CTO HarmonyOS Developer Community
The HarmonyOS Developer Community is a learning-oriented community for developers to learn, communicate, ask questions, and share.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
