Migrate from LeanCloud
This document helps you migrate your project from LeanCloud to CloudBase.
Migration Overview
Feature Comparison
| LeanCloud | CloudBase | Description |
|---|---|---|
| Data Storage | Document Database | Both are JSON document storage |
| Cloud Engine | Cloud Functions/CloudRun | Backend code hosting |
| File Service | Cloud Storage | File storage service |
| User System | Identity Authentication | User authentication service |
| Instant Messaging | - | Need to implement yourself or use third-party services |
| Push Service | - | Need to use Tencent Cloud Push Service |
Data Storage Migration
1. Export LeanCloud Data
Export data in LeanCloud Console:
- Go to "Data Storage" → "Data Management"
- Select the Class to export
- Click "Export", select JSONL format (one JSON object per line)
LeanCloud exports JSONL files with one record per line, for example:
{"objectId": "6666e6b6b6666666bb66b66b", "createdAt": "2025-07-02T07:58:45.609Z", "updatedAt": "2025-07-02T07:58:53.087Z", "email": "user@example.com", "username": "testuser"}
2. Data Format Conversion
LeanCloud and CloudBase have different data formats and need conversion. We provide a one-click intelligent migration script:
- ✅ Automatically convert to CloudBase format
- ✅ Intelligently handle JSONL format (one object per line)
- ✅ Support Pointer relationship conversion
- ✅ Support GeoPoint geolocation conversion
Field Conversion Mapping Table
| LeanCloud Field | CloudBase Field | Description |
|---|---|---|
objectId | _id | Data unique ID |
objectId | _openid | CloudBase user ID |
objectId | leancloud_objectId | Retain original ID for data tracing |
createdAt | _createTime | ISO 8601 → millisecond timestamp |
updatedAt | _updateTime | ISO 8601 → millisecond timestamp |
Pointer | _ref_* | Association reference marker (need manual handling) |
GeoPoint | {type, coordinates} | GeoJSON format [longitude, latitude] |
ACL | (delete) | CloudBase uses security rules instead |
authData | uid | Extract uid field, delete authData |
| Other fields | (fully preserved) | email, username, etc. |
Using Migration Script
Step 1: Create directory structure
migration/
├── leancloud-export/ # Place LeanCloud exported JSONL files
├── cloudbase-import/ # Output directory (auto-created)
└── cloudbase-migrate-leancloud.cjs # Migration script
Step 2: Create migration script cloudbase-migrate-leancloud.cjs
#!/usr/bin/env node
/**
* LeanCloud → CloudBase Data Migration Tool
*
* Features:
* - Convert LeanCloud data format to CloudBase format
* - Map objectId → _id and _openid
* - Convert timestamps to millisecond format
* - Support Pointer and GeoPoint type conversion
*/
const fs = require('fs');
const path = require('path');
// Configuration
const CONFIG = {
inputDir: path.join(__dirname, 'leancloud-export'),
outputDir: path.join(__dirname, 'cloudbase-import'),
keepOriginalId: true,
excludeFields: ['ACL', '__type', 'className'],
};
// Convert ISO 8601 time to millisecond timestamp
function convertTimestamp(isoString) {
if (!isoString) return null;
try {
return new Date(isoString).getTime();
} catch (error) {
console.warn(`⚠️ Time conversion failed: ${isoString}`);
return null;
}
}
// Extract uid from authData
function extractAuthDataUid(authData) {
if (!authData || typeof authData !== 'object') return null;
for (const provider of Object.keys(authData)) {
const providerData = authData[provider];
if (providerData?.uid) return providerData.uid;
}
return null;
}
// Convert Pointer type
function convertPointer(pointer, fieldName) {
if (!pointer || pointer.__type !== 'Pointer') return pointer;
return {
_ref_className: pointer.className,
_ref_objectId: pointer.objectId,
_ref_note: `Need manual replacement with CloudBase _id (original field: ${fieldName})`
};
}
// Convert GeoPoint type to GeoJSON format
function convertGeoPoint(geoPoint) {
if (!geoPoint || geoPoint.__type !== 'GeoPoint') return geoPoint;
const { latitude, longitude } = geoPoint;
if (typeof latitude !== 'number' || typeof longitude !== 'number') {
console.warn(`⚠️ GeoPoint coordinates invalid`);
return geoPoint;
}
// CloudBase uses GeoJSON format: [longitude, latitude]
return {
type: 'Point',
coordinates: [longitude, latitude]
};
}
// Recursively convert special types
function convertSpecialTypes(obj, fieldName = 'root') {
if (!obj || typeof obj !== 'object') return obj;
if (obj.__type === 'Pointer') return convertPointer(obj, fieldName);
if (obj.__type === 'GeoPoint') return convertGeoPoint(obj);
if (Array.isArray(obj)) {
return obj.map((item, index) => convertSpecialTypes(item, `${fieldName}[${index}]`));
}
const result = {};
Object.keys(obj).forEach(key => {
result[key] = convertSpecialTypes(obj[key], key);
});
return result;
}
// Convert single record
function convertRecord(leancloudRecord) {
const cloudbaseRecord = {};
// Map objectId
if (leancloudRecord.objectId) {
cloudbaseRecord._id = leancloudRecord.objectId;
cloudbaseRecord._openid = leancloudRecord.objectId;
if (CONFIG.keepOriginalId) {
cloudbaseRecord.leancloud_objectId = leancloudRecord.objectId;
}
}
// Convert timestamps
if (leancloudRecord.createdAt) {
cloudbaseRecord._createTime = convertTimestamp(leancloudRecord.createdAt);
}
if (leancloudRecord.updatedAt) {
cloudbaseRecord._updateTime = convertTimestamp(leancloudRecord.updatedAt);
}
// Extract uid from authData
if (leancloudRecord.authData) {
const uid = extractAuthDataUid(leancloudRecord.authData);
if (uid) cloudbaseRecord.uid = uid;
}
// Copy other fields and convert special types
Object.keys(leancloudRecord).forEach(key => {
if (!['objectId', 'createdAt', 'updatedAt', 'authData', ...CONFIG.excludeFields].includes(key)) {
cloudbaseRecord[key] = convertSpecialTypes(leancloudRecord[key], key);
}
});
return cloudbaseRecord;
}
// Convert JSONL file
function convertFile(inputFile, outputFile) {
console.log(`\n📄 Converting file: ${path.basename(inputFile)}`);
const content = fs.readFileSync(inputFile, 'utf-8').trim();
if (!content) {
console.log(' ⚠️ File is empty, skipping');
return { records: 0 };
}
const lines = content.split(/\r?\n/).filter(line => line.trim());
console.log(` Found ${lines.length} lines of data`);
const cloudbaseRecords = [];
let pointerCount = 0, geoPointCount = 0;
lines.forEach((line, index) => {
try {
const record = convertRecord(JSON.parse(line));
const recordStr = JSON.stringify(record);
if (recordStr.includes('_ref_')) pointerCount++;
if (recordStr.includes('"type":"Point"')) geoPointCount++;
cloudbaseRecords.push(record);
} catch (error) {
console.log(` ⚠️ Line ${index + 1} parsing failed: ${error.message}`);
}
});
if (pointerCount > 0) console.log(` 🔗 Detected ${pointerCount} Pointer references`);
if (geoPointCount > 0) console.log(` 📍 Detected ${geoPointCount} GeoPoints`);
// Output JSONL format
const jsonlContent = cloudbaseRecords.map(r => JSON.stringify(r)).join('\n');
fs.writeFileSync(outputFile, jsonlContent, 'utf-8');
console.log(` ✅ Conversion successful: ${cloudbaseRecords.length} records`);
return { records: cloudbaseRecords.length };
}
// Main function
function main() {
console.log('🚀 Starting LeanCloud → CloudBase data migration\n');
if (!fs.existsSync(CONFIG.inputDir)) {
console.error(`❌ Input directory does not exist: ${CONFIG.inputDir}`);
return;
}
if (!fs.existsSync(CONFIG.outputDir)) {
fs.mkdirSync(CONFIG.outputDir, { recursive: true });
}
const files = fs.readdirSync(CONFIG.inputDir).filter(f => f.endsWith('.jsonl'));
if (files.length === 0) {
console.error('❌ No JSONL files found');
return;
}
console.log(`📁 Found ${files.length} files to process`);
let totalRecords = 0;
files.forEach(file => {
const inputFile = path.join(CONFIG.inputDir, file);
const outputFile = path.join(CONFIG.outputDir, file.replace('.jsonl', '.json'));
const result = convertFile(inputFile, outputFile);
totalRecords += result.records;
});
console.log('\n============================================================');
console.log(`🎉 Migration complete! Converted ${totalRecords} records`);
console.log(` Output directory: ${CONFIG.outputDir}`);
console.log('\n📌 Next step: Import converted files in CloudBase Console');
}
main();
Step 3: Run migration script
node cloudbase-migrate-leancloud.cjs
Output example:
🚀 Starting LeanCloud → CloudBase data migration
📁 Found 1 files to process
📄 Converting file: lc_user_masked.jsonl
Found 1162 lines of data
🔗 Detected 25 Pointer references
📍 Detected 10 GeoPoints
✅ Conversion successful: 1162 records
============================================================
🎉 Migration complete! Converted 1162 records
Output directory: cloudbase-import
📌 Next step: Import converted files in CloudBase Console
Conversion Example
LeanCloud original data:
{"objectId": "6666e6b6b6666666bb66b66b", "createdAt": "2025-07-02T07:58:45.609Z", "updatedAt": "2025-07-02T07:58:53.087Z", "email": "user@example.com", "username": "testuser"}
CloudBase converted:
{"_id":"6666e6b6b6666666bb66b66b","_openid":"6666e6b6b6666666bb66b66b","leancloud_objectId":"6666e6b6b6666666bb66b66b","_createTime":1751443125609,"_updateTime":1751443133087,"email":"user@example.com","username":"testuser"}
Pointer Relationship Conversion
LeanCloud original data:
{
"objectId": "post123",
"title": "Test Article",
"author": {
"__type": "Pointer",
"className": "_User",
"objectId": "user123"
}
}
CloudBase converted:
{
"_id": "post123",
"title": "Test Article",
"author": {
"_ref_className": "_User",
"_ref_objectId": "user123",
"_ref_note": "Need manual replacement with CloudBase _id (original field: author)"
}
}
Pointer references will be marked as _ref_* fields, after import need to manually or via script replace _ref_objectId with corresponding CloudBase _id.
GeoPoint Geolocation Conversion
LeanCloud original data:
{
"location": {
"__type": "GeoPoint",
"latitude": 22.5431,
"longitude": 114.0579
}
}
CloudBase converted (GeoJSON format):
{
"location": {
"type": "Point",
"coordinates": [114.0579, 22.5431]
}
}
GeoPoint will be automatically converted to GeoJSON format, coordinate order is [longitude, latitude], CloudBase will automatically recognize it on import.
3. Import to CloudBase
In the console:
- Login to CloudBase Console
- Go to "Document Database" → "Data Management"
- Create corresponding collections
- Click "Import" to upload converted JSON files
Console import has a maximum limit of 50MB. If data files exceed this limit, please use the batch write script below.
4. Large Data Volume Batch Write
When data volume is large (exceeds 50MB), use script for batch write:
// batch-import.js
const cloudbase = require('@cloudbase/node-sdk');
const fs = require('fs');
const app = cloudbase.init({
env: 'your-env-id', // Replace with your environment ID
secretId: 'your-secret-id', // Replace with your SecretId
secretKey: 'your-secret-key', // Replace with your SecretKey
});
const db = app.database();
const BATCH_SIZE = 100; // Records per batch
async function batchImport(collectionName, jsonFile) {
const content = fs.readFileSync(jsonFile, 'utf-8').trim();
const lines = content.split(/\r?\n/).filter(line => line.trim());
const total = lines.length;
let imported = 0;
console.log(`Starting import of ${total} records to ${collectionName}...`);
for (let i = 0; i < total; i += BATCH_SIZE) {
const batch = lines.slice(i, i + BATCH_SIZE).map(line => JSON.parse(line));
const tasks = batch.map(item => db.collection(collectionName).add(item));
await Promise.all(tasks);
imported += batch.length;
console.log(`Progress: ${imported}/${total} (${(imported/total*100).toFixed(1)}%)`);
}
console.log(`Import complete! Total ${imported} records`);
}
// Usage example
batchImport('your-collection', 'cloudbase-import/your-file.json');
Install dependencies and run:
npm install @cloudbase/node-sdk
node batch-import.js
- SecretId and SecretKey can be obtained from Tencent Cloud Access Management
- Recommend splitting large files into multiple small files for easier resumable upload
5. Configure Security Rules
Since CloudBase uses security rules to replace LeanCloud's ACL permissions, after importing data you need to configure security rules:
Example 1: Public read, only creator can write
{
"read": true,
"write": "doc._openid == auth.openid"
}
Example 2: Only logged-in users can read and write
{
"read": "auth != null",
"write": "auth != null"
}
Example 3: Role-based permissions
{
"read": "auth != null",
"write": "get('database.users.${auth.uid}').role == 'admin'"
}
For more security rule configurations, refer to Security Rules Documentation.
Cloud Engine Migration
LeanCloud Cloud Engine projects can be migrated to CloudBase CloudRun or Cloud Functions. We provide detailed migration guides, including:
- leanengine.yaml configuration mapping: How to convert LeanCloud configuration to CloudRun deployment configuration
- Dockerfile-free deployment: CloudRun supports automatic framework recognition, no need to write Dockerfile
- Hook migration: How to implement hooks like beforeSave/afterSave through cloud function encapsulation
- Scheduled task migration: How to migrate Cron tasks to cloud function scheduled triggers
- Complete feature comparison table: Correspondence between LeanCloud API and CloudBase API
Please refer to LeanCloud Cloud Engine Migration to CloudRun/Cloud Functions Guide for detailed migration steps and code examples.
Quick Reference
| LeanCloud Cloud Engine Feature | CloudBase Corresponding Solution |
|---|---|
leanengine.yaml configuration | CloudRun deployment configuration |
AV.Cloud.define() | Cloud Function exports.main |
AV.Cloud.beforeSave() | Cloud Function encapsulating data operations |
AV.Cloud.afterSave() | Cloud Function encapsulating data operations |
| Scheduled tasks (Cron) | Scheduled triggers |
| Environment variables | CloudRun/Cloud Function environment variables |
Environment Variable Migration
Configure environment variables in CloudRun or Cloud Function console to replace original LeanCloud environment variables:
| LeanCloud Environment Variable | CloudBase Alternative | Description |
|---|---|---|
LEANCLOUD_APP_ID | ENV_ID | CloudBase environment ID |
LEANCLOUD_APP_KEY | Not needed | CloudRun internal auto-authentication |
LEANCLOUD_APP_MASTER_KEY | Not needed | CloudRun internal auto-authentication |
LEANCLOUD_APP_PORT | PORT | Service listening port |
LEANCLOUD_APP_ENV | TCB_ENV | Environment identifier (customizable) |
Custom environment variables originally configured in LeanCloud console need to be reconfigured in CloudRun or Cloud Function console.
Hook Migration Solution
CloudBase does not support database triggers, LeanCloud's beforeSave, afterSave and other Hooks need to be implemented through cloud function encapsulating data operations:
Migration Approach: Encapsulate database operations in cloud functions, clients operate data by calling cloud functions instead of directly operating the database.
LeanCloud beforeSave Hook:
// LeanCloud - Automatically process before save
AV.Cloud.beforeSave('Todo', async (request) => {
const todo = request.object;
if (!todo.get('title')) {
throw new AV.Cloud.Error('Title cannot be empty');
}
todo.set('status', 'pending');
});
CloudBase Cloud Function Encapsulation:
// CloudBase Cloud Function - functions/addTodo/index.js
const cloudbase = require('@cloudbase/node-sdk');
const app = cloudbase.init({ env: process.env.ENV_ID });
const db = app.database();
exports.main = async (event, context) => {
const { title, content } = event;
// beforeSave logic: validation and preprocessing
if (!title) {
return { success: false, error: 'Title cannot be empty' };
}
// Add data
const result = await db.collection('Todo').add({
title,
content,
status: 'pending', // Automatically set default value
_createTime: Date.now(),
});
// afterSave logic: subsequent processing (e.g., send notification)
// await sendNotification(result.id);
return { success: true, id: result.id };
};
Client call:
// Client operates data through cloud function, not directly operate database
const result = await app.callFunction({
name: 'addTodo',
data: { title: 'New Task', content: 'Task content' }
});
- Encapsulate all data operations requiring Hooks as cloud functions
- Clients uniformly operate data through cloud functions
- Can implement validation, default values, association operations, etc. in cloud functions
Simple Example
LeanCloud Cloud Function:
// LeanCloud
const AV = require('leanengine');
AV.Cloud.define('hello', async (request) => {
const { name } = request.params;
return { message: `Hello, ${name}!` };
});
CloudBase Cloud Function:
// CloudBase Cloud Function
exports.main = async (event, context) => {
const { name } = event;
return { message: `Hello, ${name}!` };
};
CloudBase CloudRun (Express):
// CloudBase CloudRun
const express = require('express');
const app = express();
app.use(express.json());
app.post('/hello', (req, res) => {
const { name } = req.body;
res.json({ message: `Hello, ${name}!` });
});
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
File Storage Migration
We provide an official migration script tool to help you batch migrate files stored in LeanCloud to Tencent CloudBase Cloud Storage.
This migration solution requires using the official provided migration script tool. Please download the script package first:
➡️ Download LeanCloud Migration Tool
🚀 After downloading, extract to local, please carefully read the README.md document, and follow the steps below for configuration and execution.
Features
- ✅ Read all file metadata from LeanCloud
_Filetable - ✅ Automatically construct URLs and batch download files
- ✅ Batch upload to Tencent CloudBase Cloud Storage
- ✅ Support concurrency control to improve migration efficiency
- ✅ Automatically retry failed downloads
- ✅ Generate detailed migration report
Project Structure
Original Structure (after extraction)
This is the file structure you see after extracting the zip package:
leancloud_storage_migrate/
├── migrate.js # Main migration script (core file)
├── package.json # Project dependency configuration file
└── README.md # Project documentation
These 3 files are the original project files, need manual configuration before use.
Structure after Installing Dependencies and Running Script
leancloud_storage_migrate/
├── migrate.js # Main migration script (core file)
├── package.json # Project dependency configuration file
├── package-lock.json # Dependency version lock file (auto-generated)
├── README.md # Project documentation
├── .gitignore # Git ignore file configuration
├── node_modules/ # Dependency package directory (generated after npm install)
├── temp_files/ # Temporary file storage directory (auto-created at runtime, auto-deleted after completion)
└── migration_report.json # Migration report file (generated after completion)
Quick Start
Step 1: Install Node.js Dependencies
Run the following command in the project directory to install required dependencies:
cd /path/to/leancloud_storage_migrate
npm install
This will automatically install the following dependency packages:
leancloud-storage- LeanCloud SDK@cloudbase/node-sdk- Tencent CloudBase Node.js SDK
Step 2: Configure Parameters
Open the migrate.js file, find the configuration area (approximately lines 17-32), fill in your configuration information:
// LeanCloud Configuration
const LEANCLOUD_CONFIG = {
appId: 'YOUR_LEANCLOUD_APP_ID', // 👈 Replace with your LeanCloud App ID
appKey: 'YOUR_LEANCLOUD_APP_KEY', // 👈 Replace with your LeanCloud App Key
serverURL: 'https://YOUR_LEANCLOUD_SERVER_URL', // 👈 Replace with your API domain
fileDomain: 'https://YOUR_FILE_DOMAIN' // 👈 Replace with your file domain
};
// Tencent CloudBase Configuration
const CLOUDBASE_CONFIG = {
env: 'YOUR_ENV_ID', // Tencent CloudBase environment ID
secretId: 'YOUR_SECRET_ID', // Tencent Cloud API key SecretId
secretKey: 'YOUR_SECRET_KEY' // Tencent Cloud API key SecretKey
};
LeanCloud Configuration:
- Login to LeanCloud Console
- Select your application
- Go to "Settings" → "App Credentials", get
App IDandApp Key - Go to "Settings" → "Domain Binding", get API domain (
serverURL) and file domain (fileDomain)
Tencent CloudBase Configuration:
- Login to Tencent CloudBase Platform
- Select your environment, get environment ID (
env) - Login to Tencent Cloud API Key Management
- Create or view key, get
SecretIdandSecretKey
⚠️ Important: Configure Security Domain
- Login to Tencent CloudBase Platform
- Go to "Environment Management" → "Security Sources"
- Add your domain to the security domain list (avoid CORS errors)
Step 3: Run Migration Script
After configuration is complete, execute the following command to start migration:
npm start
Or run directly with Node.js:
node migrate.js
Step 4: View Results
The script will display progress information in real-time:
========================================
LeanCloud → Tencent CloudBase File Migration Tool
========================================
Starting to query LeanCloud _File table...
Queried 50 files...
✓ Total 50 files queried
Starting file migration, concurrency: 5
----------------------------------------
[1] Processing file: example.jpg
Download URL: https://xxx.com/xxx.jpg
Downloading...
✓ Download complete
Uploading to CloudBase: migrated/example.jpg
✓ Upload complete, fileID: cloud://xxx...
[2] Processing file: photo.png
Download URL: https://xxx.com/yyy.png
Downloading...
✓ Download complete
Uploading to CloudBase: migrated/photo.png
✓ Upload complete, fileID: cloud://yyy...
...
========================================
Migration Complete!
----------------------------------------
Total: 50 files
Success: 48
Failed: 2
Migration report saved to: ./migration_report.json
After completion, a migration_report.json report file will be generated in the current directory.
Optional Configuration
You can adjust the following configurations to optimize migration performance:
const DOWNLOAD_CONFIG = {
tempDir: './temp_files', // Temporary file storage directory
concurrency: 5, // Concurrent download count (recommend 3-10)
retryTimes: 3, // Download failure retry times
timeout: 30000 // Request timeout (milliseconds)
};
Migration Process
- Query file list: Query all files from LeanCloud
_Filetable - Download files: Construct URL based on
keyand download to local temporary directory - Upload files: Upload files to Tencent CloudBase Cloud Storage
- Generate report: Generate
migration_report.jsonreport file - Clean temporary files: Delete local temporary files
Output Results
After migration is complete, a migration_report.json report file will be generated, containing:
{
"timestamp": "2026-01-21T10:30:00.000Z",
"summary": {
"total": 100,
"success": 98,
"failed": 2
},
"successList": [
{
"objectId": "xxx",
"name": "example.jpg",
"fileID": "cloud://xxx.cloudbase.net/xxx",
"cloudPath": "migrated/example.jpg"
}
],
"errorList": [
{
"objectId": "yyy",
"name": "failed.png",
"error": "Download timeout"
}
]
}
Notes
- Network Stability: Ensure stable network connection, large file migration may take longer
- Disk Space: Ensure sufficient disk space to store temporary files
- Concurrency Count: Adjust concurrency based on network bandwidth, avoid too high causing request failures
- Retry Mechanism: Failed files will automatically retry, final failures will be recorded in the report
- Cloud Path: All files will be uploaded to
migrated/directory, can be modified as needed - fileID Saving: Uploaded
fileIDwill be recorded in the report, recommend saving for future use
Troubleshooting
Download Failed
- Check if
fileDomainconfiguration is correct - Check if network connection is normal
- Try increasing
timeouttimeout
Upload Failed
- Confirm Tencent CloudBase environment ID is correct
- Check if security domain is configured
- Confirm cloud storage quota is sufficient
CORS Error
- Login to Tencent CloudBase Console
- Add your domain in "Security Configuration" → "Security Sources"
User System Migration
This section helps you migrate LeanCloud user system (_User table) to CloudBase user system.
Migration Goals
- Write LeanCloud
objectIdto CloudBase user table (using admin API'sUidfield), achieving original ID remains unchanged - Synchronize user-related fields (e.g.,
name, nickname, phone, email, avatar, etc.) - After migration, reconfigure your business permission logic based on security rules (replace LeanCloud ACL)
Login Method Comparison
Migration solution heavily depends on your current login method:
- If you use username/email/phone + password: Need to plan a transition plan for "password cannot be directly migrated" (verification code login priority / temporary password / dual-stack).
- If you use email/phone + verification code: Migration is relatively simple, focus is on writing email/phone fields correctly and ensuring security rules and business permissions are correct.
| Login Method | LeanCloud | CloudBase |
|---|---|---|
| Username + Password | ✅ Built-in support | ✅ Built-in support |
| Email + Verification Code | ✅ Built-in support | ✅ Built-in support |
| Phone + Verification Code | ✅ Built-in support | ✅ Built-in support |
| WeChat Login | ✅ Third-party login | ✅ Deep support |
| UnionID Linking | ✅ Support | ✅ Support |
| QQ Login | ✅ Third-party login | ✅ OAuth support |
| Weibo Login | ✅ Third-party login | ✅ OAuth support |
| Apple Login | ✅ Built-in support | 🕐 Coming soon |
| Anonymous Login | ✅ Built-in support | ✅ Built-in support |
| Custom Login | ❌ Not supported | ✅ Supported |
CloudBase and LeanCloud User System Differences
- User Table Structure: CloudBase user system's built-in fields are a fixed set (e.g.,
Uid,Name,Phone,Email, etc.), recommend putting your business custom fields in a self-built collection (e.g.,user_profile), linked byUid. - Password Migration: LeanCloud usually does not allow exporting plain text passwords; even if you can get the hash, cannot directly write to CloudBase user system. You need to choose a "post-migration reset/reset" strategy (solutions provided below).
- Username Validation Rule Differences:
- CloudBase admin API allows
Nameto support special characters like@when creating users (more lenient). - But "user self-registration" frontend/client validation rules may be stricter (e.g., not allowing
@), the two are not completely consistent.
- CloudBase admin API allows
Migration Process
- Export LeanCloud user data (export from
_Useras JSON) - Field mapping and cleaning (
objectId→Uid, handle correspondence ofname/phone/email) - Call CloudBase admin API to batch create users (
CreateUser) - Synchronize custom business fields (write to self-built collection, linked by
Uid) - Configure security rules and permission logic (replace LeanCloud ACL)
- Sample verification and rollback plan (
DescribeUserList/DeleteUsers)
Prerequisites
- CloudBase Environment: Prepare
EnvId(environment ID). - Access Credentials: Prepare Tencent Cloud keys that can call CloudBase admin API (
SecretId/SecretKey). Recommend:- Use sub-account + minimum permission policy
- Inject keys through environment variables, avoid writing in code or documentation
- API Documentation: CloudBase Identity Authentication / User Management API Documentation
Field Mapping
Taking LeanCloud _User common fields as example (your actual fields are based on export):
| LeanCloud Field | Description | CloudBase Field | Write Method |
|---|---|---|---|
objectId | User unique identifier | Uid | Required: Write to CreateUser.Uid, achieving "original ID remains unchanged" |
name / username | Login username (may be username / phone / email address) | Name | Recommend priority writing to Name |
mobilePhoneNumber | Phone number | Phone | If exists and compliant, write to Phone, after writing user can use phone verification code login |
email | Email | If exists and compliant, write to Email, after writing user can use email verification code login | |
nickname | Nickname | NickName | Optional |
avatar / avatarUrl | Avatar link | AvatarUrl | Optional (need public network accessible) |
| Other business fields | E.g., membership level, channel, invitation relationship, etc. | Not recommend writing to user system table | Recommend writing to self-built collection user_profile, linked by Uid |
If in your LeanCloud business, users use phone + password or email + password login, and you store phone/email in name (or username), then when migrating to CloudBase:
- Besides writing LeanCloud's
nameto CloudBase'sName, also need to synchronize LeanCloud'snameto CloudBase'sPhoneand/orEmailfield, otherwise users will not be able to login in the original way. - Practical suggestions:
- If
nameis like email (contains@and meets email format) → WriteEmail = name - If
nameis like phone (11 digits, etc.) → WritePhone = name - If
nameis not phone/email, don't force write toPhone/Email, please use your originalmobilePhoneNumber/emailfield, or guide users to change to verification code login.
- If
Password Migration Strategy
Because original password cannot be migrated, usually three feasible solutions:
| Solution | Description | Applicable Scenario |
|---|---|---|
| Solution 1: Verification Code Login Priority | After migration, guide users to login with SMS/email verification code, then reset password on "Set Password" page | Recommended, good user experience |
| Solution 2: Set Temporary Password | Generate temporary password for each user during import (script can generate random strong password), force change after first login | Need to notify users of temporary password |
| Solution 3: Login State Migration | If you have self-developed authentication/SSO, can short-term dual-stack: login goes to old system, business data gradually switches to CloudBase; finally unify password system | Complex scenario |
Migration Script
We provide a one-click migration script with features including:
- ✅ Read LeanCloud exported user JSON (array)
- ✅ Call CloudBase admin API
CreateUserto batch create users - ✅ Write
objectIdtoUid, keep original ID unchanged - ✅ If user already exists (returns duplicate data), automatically call
ModifyUserto update fields (default does not reset password) - ✅ Optional: Mirror
nametoPhone/Email(for phone/email password login scenario) - ✅ Support multiple password modes: don't write password / unified default password / generate random temporary password for each user
1. Prepare LeanCloud Export File
Export _User table as JSON array format in LeanCloud console, example:
[
{
"objectId": "6864e6b5b9570274df85a79e",
"username": "sample@163.com",
"email": "sample@163.com",
"emailVerified": true,
"mobilePhoneVerified": false,
"nickname": "sample1",
"createdAt": "2025-07-02T07:58:45.609Z",
"updatedAt": "2025-07-02T07:58:53.087Z",
"ACL": { "*": { "read": true, "write": true } }
},
{
"objectId": "6870cf46bf6125518c3c7979",
"username": "88888888@qq.com",
"email": "88888888@qq.com",
"emailVerified": false,
"mobilePhoneVerified": false,
"nickname": "sample2",
"createdAt": "2025-07-11T08:45:58.532Z",
"updatedAt": "2025-07-11T08:45:58.532Z",
"ACL": { "*": { "read": true, "write": true } }
},
{
"objectId": "6893900f6f00df1bd11a0499",
"username": "4umxxxxfb0",
"emailVerified": false,
"mobilePhoneVerified": false,
"nickname": "sample3",
"createdAt": "2025-08-06T17:25:35.704Z",
"updatedAt": "2026-01-10T11:37:08.378Z",
"authData": {
"lc_apple": {
"uid": "001842.56ca44c39bf84bb4aaa377c87fe57613.1555",
"token_type": "Bearer",
"expires_in": 3600
}
},
"ACL": { "*": { "read": true, "write": true } }
}
]