Migrating from Firebase
This document helps you migrate your project from Firebase to CloudBase.
Migration Overview
Feature Comparison
| Firebase | CloudBase | Description |
|---|---|---|
| Firestore | Document Database | Both are NoSQL document storage |
| Cloud Functions | Cloud Functions | Serverless function service |
| Cloud Run | Image-based HTTP Cloud Functions | Container image hosting |
| Cloud Storage | Cloud Storage | File storage service |
| Authentication | Authentication | User authentication service |
| Realtime Database | Realtime Data Push | Real-time data synchronization |
Data Migration
Exporting Firebase Data
Firebase DataStorage Database Export
Since Firebase's official export feature only supports exporting to Google Cloud Datastore's BigQuery format, it is recommended to export in standard JSON format using a script.
First, create a Firebase Admin SDK key in the Firebase Console under the Service Accounts page, and download it.
Then clone https://github.com/m417z/node-firestore-import-export/tree/fork, navigate to the repository directory, and run npm install && npm run build to trigger the build. After the build is complete, run:
GOOGLE_APPLICATION_CREDENTIALS=<key_path> npm run export -- -b firebase-export.json
This will export the database to firebase-export.json.
{
"__collections__": {
"albums": {
"HVskzxL7SbQ4CrMV2KoO": {
"description": "A new collection of memories.",
"ownerId": "6TZnxEYS5JVooGWUXf4fvyKBbA33",
"name": "B",
"coverImageUrl": "https://firebasestorage.googleapis.com/...",
"__collections__": {
"photos": {
"3BTRlw1rVSQjfMJzzZ1S": {
"albumId": "HVskzxL7SbQ4CrMV2KoO",
"uploaderId": "6TZnxEYS5JVooGWUXf4fvyKBbA33",
"url": "https://firebasestorage.googleapis.com/...",
"title": "logo.png",
"createdAt": {
"__datatype__": "timestamp",
"value": {
"_seconds": 1770606013,
"_nanoseconds": 801000000
}
},
"location": {
"__datatype__": "geopoint",
"value": {
"_latitude": 32,
"_longitude": 120
}
},
"__collections__": {}
}
}
}
}
}
}
}
Where:
- The top-level
__collections__contains each collection (e.g.,albums) - Keys under a collection are document IDs (e.g.,
HVskzxL7SbQ4CrMV2KoO) - The
__collections__within a document represents its subcollections (e.g.,photos) - Special types like
timestampandgeopointare encoded as objects with__datatype__andvaluefields. These need to be converted to CloudBase-supported timestamp and GeoJSON formats in the conversion script.
Firebase Authentication Export
Firebase CLI supports batch exporting users. First, install the CLI:
npm i -g firebase-cli
Log in to Firebase:
firebase login
List project IDs:
firebase projects:list
Finally, export as JSON:
firebase auth:export user.json --project <project_id_from_previous_step>
The user.json exported by firebase auth:export is a JSON file containing a users array, where each element is a user record. The structure is roughly as follows (example trimmed from an actual export file, with sensitive data redacted):
{
"users": [
{
"localId": "7hQ2mXbK9vP4sT1cUy3Zr8NaLd0w",
"email": "user@example.com",
"emailVerified": false,
"passwordHash": "aS9xK0lmT3p5VnF4c2hDZ0JhR1p5eGd2bE9YUm1qU3hMUG9uRkE9PQ==",
"salt": "c2FsdF9leGFtcGxlX2Jhc2U2NA==",
"createdAt": "1700000000000",
"lastSignedInAt": "1700003600000",
"providerUserInfo": []
}
]
}
Data Format Conversion
Firebase and CloudBase have different data formats, so conversion is required.
Field Conversion Reference
| Firebase Field/Type | CloudBase Field/Format | Description |
|---|---|---|
| Document ID (object key) | _id | Firebase document ID is used as the object key and needs to be extracted as the _id field |
__collections__ | (remove) | Subcollection marker; subcollection data should be processed separately |
{"__datatype__": "timestamp", "value": {"_seconds": ..., "_nanoseconds": ...}} | Millisecond timestamp | Convert using _seconds * 1000 + _nanoseconds / 1000000 |
{"__datatype__": "geopoint", "value": {"_latitude": ..., "_longitude": ...}} | {type: "Point", coordinates: [longitude, latitude]} | Convert to GeoJSON format. Note the coordinate order is [longitude, latitude] |
createdAt (Timestamp type) | _createTime | If present, convert to millisecond timestamp |
updatedAt (Timestamp type) | _updateTime | If present, convert to millisecond timestamp |
userId / ownerId / uploaderId | _openid | User-related fields, mapped to CloudBase user ID |
| Other regular fields | (keep as-is) | Strings, numbers, booleans, arrays, objects, and other business fields |
Conversion Example
Firebase original data (a single document extracted from the export file):
{
"albumId": "HVskzxL7SbQ4CrMV2KoO",
"uploaderId": "6TZnxEYS5JVooGWUXf4fvyKBbA33",
"title": "logo.png",
"createdAt": {
"__datatype__": "timestamp",
"value": {
"_seconds": 1770606013,
"_nanoseconds": 801000000
}
},
"location": {
"__datatype__": "geopoint",
"value": {
"_latitude": 32,
"_longitude": 120
}
}
}
After CloudBase conversion (document ID 3BTRlw1rVSQjfMJzzZ1S as _id):
{
"_id": "3BTRlw1rVSQjfMJzzZ1S",
"albumId": "HVskzxL7SbQ4CrMV2KoO",
"_openid": "6TZnxEYS5JVooGWUXf4fvyKBbA33",
"uploaderId": "6TZnxEYS5JVooGWUXf4fvyKBbA33",
"title": "logo.png",
"_createTime": 1770606013801,
"location": {
"type": "Point",
"coordinates": [120, 32]
}
}
Conversion notes:
- The document ID (
3BTRlw1rVSQjfMJzzZ1S) is extracted as the_idfield - The
createdAtTimestamp is converted to a millisecond timestamp:1770606013 * 1000 + 801000000 / 1000000 = 1770606013801 - The
locationGeoPoint is converted to GeoJSON:[longitude, latitude]=[120, 32] uploaderIdis both retained as the original field and mapped to_openid(depending on business requirements)
Importing to CloudBase
In the console:
- Log in to the CloudBase Console
- Navigate to "Document Database" → "Data Management"
- Create the corresponding collections
- Click "Import" to upload the converted JSON file
The console import has a maximum limit of 50MB. If your data file exceeds this limit, use a batch write script. :::
You can refer to the data conversion script example. Please write scripts based on the actual field names used in your project's business logic to generate the JSON files needed for import.
Configuring Security Rules
Since CloudBase uses security rules to replace Firebase's security rules, you need to configure security rules after importing data:
Example 1: Public read, only creator can write
{
"read": true,
"write": "doc._openid == auth.openid"
}
For more security rule configurations, refer to the Security Rules Documentation.
Cloud Functions Migration
Firebase Cloud Functions can be migrated to CloudBase Cloud Functions.
Simple Example
Firebase Cloud Function:
// Firebase
const functions = require('firebase-functions');
exports.hello = functions.https.onRequest((req, res) => {
const { name } = req.body;
res.json({ message: `Hello, ${name}!` });
});
CloudBase Cloud Function:
// CloudBase Cloud Function
exports.main = async (event, context) => {
const { name } = event;
return { message: `Hello, ${name}!` };
};
Environment Variable Migration
Configure environment variables in the Cloud Functions console to replace the original Firebase environment variables:
| Firebase Environment Variable | CloudBase Equivalent | Description |
|---|---|---|
FIREBASE_PROJECT_ID | ENV_ID | CloudBase environment ID |
FIREBASE_CONFIG | Not required | Cloud Functions authenticate automatically |
File Storage Migration
Migration Steps
- Download files: Batch download files from Firebase Storage
You can use gsutil to download in bulk. For example:
gsutil -m cp -r "gs://<project prefix>.firebasestorage.app/<subpath>" .
- Upload files: Upload files to Tencent CloudBase Cloud Storage. You can use COS Browser to connect to the corresponding COS address for batch uploads.
- Update references: If necessary, update file reference paths in the database.
Container Image Hosting Migration
Firebase supports hosting container images via Cloud Run, which can be replaced with HTTP Cloud Functions.
For detailed documentation, see: Deploying Cloud Functions with Images
After deployment, the service can be accessed by configuring HTTP Access Service. Example configuration file:
{
"envId": "{{envId}}",
"functions": [
{
"name": "helloworld",
"type": "HTTP",
"imageConfig": {
"imageType": "personal",
"imageUri": "ccr.ccs.tencentyun.com/cloudbase/hono-deno-helloworld:amd64"
},
"envVariables": {
"PORT": "9000"
}
}
]
}
Note that the image must be linux/amd64 architecture and listen on port 9000.
SDK Comparison
Below is an API comparison table between Firebase SDK and CloudBase SDK to help you quickly complete code migration.
Initialization
| Operation | Firebase | CloudBase |
|---|---|---|
| Initialize SDK | firebase.initializeApp(config) | cloudbase.init({ env }) |
Firebase:
import { initializeApp } from 'firebase/app';
const app = initializeApp({
apiKey: 'your-api-key',
authDomain: 'your-project.firebaseapp.com',
projectId: 'your-project-id',
});
CloudBase:
import cloudbase from '@cloudbase/js-sdk';
const app = cloudbase.init({ env: 'your-env-id' });
📖 CloudBase SDK Initialization Documentation
Database Operations
| Operation | Firebase | CloudBase |
|---|---|---|
| Get database reference | getFirestore(app) | app.database() |
| Get collection reference | collection(db, 'collectionName') | db.collection('collectionName') |
| Query all | getDocs(collectionRef) | collection.get() |
| Query single | getDoc(docRef) | collection.doc(id).get() |
| Conditional query | where('field', '==', value) | collection.where({ field: value }) |
| Greater than | where('field', '>', value) | collection.where({ field: _.gt(value) }) |
| Less than | where('field', '<', value) | collection.where({ field: _.lt(value) }) |
| Sort | orderBy('field', 'asc') | collection.orderBy('field', 'asc') |
| Limit | limit(10) | collection.limit(10) |
| Add data | addDoc(collectionRef, data) | collection.add(data) |
| Update data | updateDoc(docRef, { field: value }) | collection.doc(id).update({ field: value }) |
| Delete data | deleteDoc(docRef) | collection.doc(id).remove() |
Query example comparison:
// Firebase
import { collection, query, where, orderBy, limit, getDocs } from 'firebase/firestore';
const q = query(
collection(db, 'Todo'),
where('status', '==', 'pending'),
where('priority', '>', 5),
orderBy('createdAt', 'asc'),
limit(20)
);
const results = await getDocs(q);
// CloudBase
const db = app.database();
const _ = db.command;
const results = await db.collection('Todo')
.where({
status: 'pending',
priority: _.gt(5)
})
.orderBy('createdAt', 'asc')
.limit(20)
.get();
📖 CloudBase Database API Documentation
Cloud Storage Operations
| Operation | Firebase | CloudBase |
|---|---|---|
| Upload file | uploadBytes(ref, file) | app.uploadFile({ cloudPath, filePath }) |
| Get file URL | getDownloadURL(ref) | app.getTempFileURL({ fileList }) |
| Delete file | deleteObject(ref) | app.deleteFile({ fileList }) |
| Download file | getBytes(ref) | app.downloadFile({ fileID }) |
File upload example comparison:
// Firebase
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage';
const storageRef = ref(storage, 'avatars/avatar.png');
await uploadBytes(storageRef, file);
const url = await getDownloadURL(storageRef);
// CloudBase
const result = await app.uploadFile({
cloudPath: 'avatars/avatar.png',
filePath: file,
onUploadProgress: (progressEvent) => {
const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);
console.log(`Upload progress: ${percent}%`);
}
});
const fileID = result.fileID;
📖 CloudBase Cloud Storage API Documentation
Cloud Functions Operations
| Operation | Firebase | CloudBase |
|---|---|---|
| Call Cloud Function | httpsCallable(functions, 'functionName') | app.callFunction({ name, data }) |
| Define Cloud Function | functions.https.onRequest() | exports.main = async (event, context) => {} |
| Get caller info | context.auth | context.auth / event.userInfo |
Cloud Function call example comparison:
// Firebase client
import { getFunctions, httpsCallable } from 'firebase/functions';
const functions = getFunctions(app);
const hello = httpsCallable(functions, 'hello');
const result = await hello({ name: 'World' });
// CloudBase client
const result = await app.callFunction({
name: 'hello',
data: { name: 'World' }
});
console.log(result.result);
📖 CloudBase Cloud Functions API Documentation
Authentication Operations
| Operation | Firebase | CloudBase |
|---|---|---|
| Get Auth object | getAuth(app) | app.auth() |
| Email/password registration | createUserWithEmailAndPassword(auth, email, password) | auth.signUp({ email, password }) |
| Email/password login | signInWithEmailAndPassword(auth, email, password) | auth.signInWithEmailAndPassword(email, password) |
| Phone verification login | signInWithPhoneNumber(auth, phone) | auth.signInWithPhoneCode(phone, code) |
| Anonymous login | signInAnonymously(auth) | auth.signInAnonymously() |
| Get current user | auth.currentUser | auth.currentUser |
| Sign out | signOut(auth) | auth.signOut() |
Login example comparison:
// Firebase - Email/password login
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
const auth = getAuth(app);
const userCredential = await signInWithEmailAndPassword(auth, 'email@example.com', 'password');
console.log('Login successful:', userCredential.user);
// CloudBase - Email/password login
const auth = app.auth();
const loginState = await auth.signInWithEmailAndPassword('email@example.com', 'password');
console.log('Login successful:', loginState.user);
📖 CloudBase Authentication API Documentation
Realtime Database
| Operation | Firebase | CloudBase |
|---|---|---|
| Realtime listener | onSnapshot(docRef, callback) | collection.watch() |
| Cancel listener | unsubscribe() | watcher.close() |
Realtime listener example comparison:
// Firebase Firestore
import { onSnapshot } from 'firebase/firestore';
const unsubscribe = onSnapshot(docRef, (snapshot) => {
console.log('Data changed:', snapshot.data());
});
// CloudBase Realtime Data Push
const db = app.database();
const watcher = db.collection('messages')
.where({ roomId: 'room1' })
.watch({
onChange: (snapshot) => {
console.log('Data changed:', snapshot.docChanges);
},
onError: (error) => {
console.error('Listener error:', error);
}
});
// Cancel listener
watcher.close();
📖 CloudBase Realtime Data Push Documentation
More API References
| Category | Documentation Link |
|---|---|
| Web SDK Full Documentation | https://docs.cloudbase.net/api-reference/webv2/initialization |
| Node.js SDK Documentation | https://docs.cloudbase.net/api-reference/server/initialization |
| Database Security Rules | https://docs.cloudbase.net/database/security-rules |
| Cloud Functions Development Guide | https://docs.cloudbase.net/cloud-function/introduce |
| Authentication Guide | https://docs.cloudbase.net/authentication/auth/introduce |
| Cloud Storage User Guide | https://docs.cloudbase.net/storage/introduce |
FAQ
Q: How to migrate Firebase security rules?
CloudBase uses a similar security rule syntax, but there are some differences. Refer to the Security Rules Documentation for migration guidance.
Q: How to replace realtime communication features?
CloudBase supports realtime data push. You can use the database realtime listener feature:
const db = app.database();
db.collection('messages')
.where({ roomId: 'xxx' })
.watch({
onChange: (snapshot) => {
console.log('Data changed:', snapshot.docs);
},
});
Q: How to ensure business continuity during migration?
A gradual migration approach is recommended:
- Deploy the CloudBase environment first and perform functional testing
- Use a dual-write strategy, writing new data to both platforms simultaneously
- After completing data migration, gradually switch traffic
- After confirming stability, decommission the Firebase service