Skip to main content

Overview

Pub Version

CloudBase Flutter SDK enables you to use CloudBase capabilities in Flutter applications, including authentication, document database, data models, MySQL database, cloud functions, cloud hosting, APIs, and more. For usage, please refer to CloudBase Flutter SDK, or check the sample code.

Note

CloudBase Flutter SDK is fully aligned with HTTP API

SDK is categorized by functionality:

  • Authentication: API methods for user registration and login, supporting multiple login methods.
  • Session Management: API methods for managing user session state and tokens.
  • User Management: API methods for retrieving, updating, and managing user information.
  • Identity Source Management: API methods for managing third-party identity source binding and unbinding.
  • Password Management: API methods for password reset and change.
  • Verification Management: API methods for verification code sending, verification, resending, CAPTCHA creation, verification, and management.
  • Document Database: Operations for NoSQL document database including collections, documents, queries, updates, deletions, aggregation, transactions, and more.
  • Data Model: Data model CRUD operations.
  • Data Source Query: Query data source aggregation list, details, Schema, and table names.
  • MySQL Database: MySQL RESTful database operations.
  • Cloud Functions: Call cloud functions and function-type cloud hosting.
  • Cloud Hosting: Call cloud hosting container services.
  • APIs: Call APIs interfaces.
  • Cloud Storage: File upload, download, delete, copy, move, and other operations.

Basic Usage Example

accessKey can be generated in CloudBase Platform/API Key Configuration

import 'package:cloudbase_flutter/cloudbase_flutter.dart';

// Initialize (async)
final app = await CloudBase.init(
env: 'your-env-id', // Replace with your environment ID
region: 'ap-shanghai', // Region, default is Shanghai
accessKey: 'your-key', // Fill in the generated Publishable Key
authConfig: AuthConfig(
detectSessionInUrl: true, // Optional: automatically detect OAuth parameters in URL
),
);

final auth = app.auth;

Authentication

signUp

Future<SignUpRes> auth.signUp(SignUpReq params)

Register a new user account using smart registration and login flow.

  • Creates a new user account
  • Uses smart registration and login flow: send verification code → wait for user input → smart judgment of user existence → auto login or register and login
  • If user already exists, directly login; if user does not exist, register new user and auto login

Parameters

params
SignUpReq

Response

Future
SignUpRes

Example

final result = await auth.signUp(SignUpReq(
email: 'user@example.com',
password: 'securePassword123',
nickname: 'New User',
));

if (result.error != null) {
print('Registration failed: ${result.error!.message}');
return;
}

// Verify verification code
final verifyResult = await result.data!.verifyOtp!(
VerifyOtpParams(token: '123456'),
);

if (verifyResult.isSuccess) {
print('Registration successful: ${verifyResult.data?.user?.id}');
}

signInAnonymously

Future<SignInRes> auth.signInAnonymously({String? providerToken})

Anonymous login, creates a temporary anonymous user account.

  • Creates a temporary anonymous user account
  • No identity verification info needed
  • Suitable for scenarios requiring temporary access

Parameters

providerToken
String?

Third-party platform token, used to associate third-party platform identity

Response

Future
SignInRes

Example

final result = await auth.signInAnonymously();

if (result.isSuccess) {
print('Anonymous login successful');
print('User ID: ${result.data?.user?.id}');
print('Is anonymous: ${result.data?.user?.isAnonymous}');
} else {
print('Anonymous login failed: ${result.error!.message}');
}

signInWithPassword

Future<SignInRes> auth.signInWithPassword(SignInWithPasswordReq params)

Login with password. Supports login via username, email, or phone number.

Parameters

params
SignInWithPasswordReq

Response

Future
SignInRes

Example

final result = await auth.signInWithPassword(
SignInWithPasswordReq(
email: 'user@example.com',
password: 'securePassword123',
),
);

if (result.isSuccess) {
print('Login successful: ${result.data?.user?.id}');
} else {
print('Login failed: ${result.error!.message}');
}

signInWithOtp

Future<SignInWithOtpRes> auth.signInWithOtp(SignInWithOtpReq params)

Login with OTP (one-time verification code). After calling, a verification code will be sent. You need to complete verification through the returned verifyOtp callback.

  • If the user does not exist, a user will be created by default. You can control whether to automatically create a user with the shouldCreateUser parameter (default is true)

Parameters

params
SignInWithOtpReq

Response

Future
SignInWithOtpRes

Example

final result = await auth.signInWithOtp(
SignInWithOtpReq(email: 'user@example.com'),
);

if (result.error != null) {
print('Failed to send verification code: ${result.error!.message}');
return;
}

// Call after user inputs verification code
final loginResult = await result.data!.verifyOtp!(
VerifyOtpParams(token: '123456'),
);

if (loginResult.isSuccess) {
print('OTP login successful: ${loginResult.data?.user?.id}');
}

signInWithOAuth

Future<SignInOAuthRes> auth.signInWithOAuth(SignInWithOAuthReq params)

Login with OAuth third-party platform. Returns authorization URL, you need to guide the user to redirect to this URL to complete authorization.

Parameters

params
SignInWithOAuthReq

Response

Future
SignInOAuthRes

Example

final result = await auth.signInWithOAuth(
SignInWithOAuthReq(provider: 'wechat'),
);

if (result.isSuccess) {
final authUrl = result.data!.url!;
print('Please redirect to authorization page: $authUrl');
// Guide user to open authUrl for authorization
}

signInWithIdToken

Future<SignInRes> auth.signInWithIdToken(SignInWithIdTokenReq params)

Login with IdToken. Suitable for scenarios where third-party platform tokens have been obtained.

Parameters

params
SignInWithIdTokenReq

Response

Future
SignInRes

Example

final result = await auth.signInWithIdToken(
SignInWithIdTokenReq(
token: 'provider-id-token',
provider: 'wechat',
),
);

if (result.isSuccess) {
print('IdToken login successful: ${result.data?.user?.id}');
} else {
print('Login failed: ${result.error!.message}');
}

signInWithCustomTicket

Future<SignInRes> auth.signInWithCustomTicket(Future<String> Function() getTicketFn)

Login with custom ticket. By passing an async function to get the ticket, the server generates the ticket and completes the login.

Parameters

getTicketFn
Future<String> Function()

Async function to get custom login ticket

Response

Future
SignInRes

Example

final result = await auth.signInWithCustomTicket(() async {
// Get custom ticket from your server
final ticket = await fetchTicketFromServer();
return ticket;
});

if (result.isSuccess) {
print('Custom ticket login successful: ${result.data?.user?.id}');
} else {
print('Login failed: ${result.error!.message}');
}

Session Management

getSession

Future<SignInRes> auth.getSession();

Get current session. If token has expired, it will be automatically refreshed.

Parameters

No parameters

Response

Future
SignInRes

Example

final result = await auth.getSession();

if (result.isSuccess) {
final session = result.data?.session;
print('Access Token: ${session?.accessToken}');
print('User: ${result.data?.user?.id}');
} else {
print('Failed to get session: ${result.error!.message}');
}

refreshSession

Future<SignInRes> auth.refreshSession([String? refreshToken])

Refresh session. Use Refresh Token to get a new Access Token.

Parameters

refreshToken
String?

Refresh token (optional, defaults to current session's refreshToken)

Response

Future
SignInRes

Example

final result = await auth.refreshSession();

if (result.isSuccess) {
print('Session refreshed');
print('New Access Token: ${result.data?.session?.accessToken}');
} else {
print('Refresh failed: ${result.error!.message}');
}

setSession

Future<SignInRes> auth.setSession(SetSessionReq params)

Set session. Restore session state with Refresh Token.

Parameters

params
SetSessionReq

Response

Future
SignInRes

Example

final result = await auth.setSession(
SetSessionReq(refreshToken: 'your-refresh-token'),
);

if (result.isSuccess) {
print('Session set successfully: ${result.data?.user?.id}');
}

signOut

Future<SignOutRes> auth.signOut([SignOutReq? params])

Logout. Clear local session and notify server to revoke token.

Parameters

params
SignOutReq?

Logout configuration options (optional)

Response

Future
SignOutRes

Example

await auth.signOut();
print("Logged out");

onAuthStateChange

OnAuthStateChangeResult auth.onAuthStateChange(OnAuthStateChangeCallback callback)

Listen for authentication state changes. Supports listening for login, logout, token refresh, and user update events.

Parameters

callback
void Function(AuthStateChangeEvent, Session?, AuthStateChangeInfo?)

State change callback function

Response

OnAuthStateChangeResult
OnAuthStateChangeResult

Example

final result = auth.onAuthStateChange((event, session, info) {
print('Auth state changed: ${event.value}');
if (session != null) {
print('User: ${session.user?.id}');
}
});

// Stop listening
result.data?.subscription.unsubscribe();

getClaims

Future<GetClaimsRes> auth.getClaims();

Get JWT Claims of current Access Token (token claims).

Parameters

No parameters

Response

Future
GetClaimsRes

Example

final result = await auth.getClaims();

if (result.isSuccess) {
final claims = result.data?.claims;
print('User ID: ${claims?.sub}');
print('Email: ${claims?.email}');
print('User groups: ${claims?.groups}');
print('Expiration: ${claims?.exp}');
}

User Management

getUser

Future<GetUserRes> auth.getUser();

Get current logged-in user info.

Parameters

No parameters

Response

Future
GetUserRes

Example

final result = await auth.getUser();

if (result.isSuccess) {
final user = result.data?.user;
print('User ID: ${user?.id}');
print('Email: ${user?.email}');
print('Nickname: ${user?.userMetadata?.nickName}');
} else {
print('Failed to get user info: ${result.error!.message}');
}

refreshUser

Future<SignInRes> auth.refreshUser();

Refresh user info. Re-fetch the latest user data from server and update local session.

Parameters

No parameters

Response

Future
SignInRes

Example

final result = await auth.refreshUser();

if (result.isSuccess) {
print('User info refreshed: ${result.data?.user?.id}');
}

updateUser

Future<UpdateUserRes> auth.updateUser(UpdateUserReq params)

Update user info. If updating email or phone number, verification code verification is required.

Parameters

params
UpdateUserReq

Response

Future
UpdateUserRes

Example

final result = await auth.updateUser(
UpdateUserReq(nickname: 'New Nickname', avatarUrl: 'https://example.com/avatar.png'),
);

if (result.isSuccess) {
print('User info updated: ${result.data?.user?.userMetadata?.nickName}');
}

deleteUser

Future<CloudBaseResponse<void>> auth.deleteUser(DeleteUserReq params)

Delete current user. Password is required for security verification.

Parameters

params
DeleteUserReq

Response

Future
CloudBaseResponse<void>

Example

final result = await auth.deleteUser(
DeleteUserReq(password: 'currentPassword'),
);

if (result.isSuccess) {
print('User deleted');
} else {
print('Deletion failed: ${result.error!.message}');
}

Identity Source Management

getUserIdentities

Future<GetUserIdentitiesRes> auth.getUserIdentities();

Get the list of identity sources bound to the current user.

Parameters

No parameters

Response

Future
GetUserIdentitiesRes

Example

final result = await auth.getUserIdentities();

if (result.isSuccess) {
for (final identity in result.data?.identities ?? []) {
print('Identity: ${identity.name} (${identity.provider})');
}
}

linkIdentity

Future<LinkIdentityRes> auth.linkIdentity(LinkIdentityReq params)

Bind third-party identity source. Will redirect to third-party authorization page to complete binding.

Parameters

params
LinkIdentityReq

Response

Future
LinkIdentityRes

Example

final result = await auth.linkIdentity(
LinkIdentityReq(provider: 'wechat'),
);

if (result.isSuccess) {
print('Identity source bound successfully: ${result.data?.provider}');
}

unlinkIdentity

Future<CloudBaseResponse<void>> auth.unlinkIdentity(UnlinkIdentityReq params)

Unbind third-party identity source.

Parameters

params
UnlinkIdentityReq

Response

Future
CloudBaseResponse<void>

Example

final result = await auth.unlinkIdentity(
UnlinkIdentityReq(provider: 'wechat'),
);

if (result.isSuccess) {
print('Identity source unbound');
}

Password Management

resetPasswordForEmail

Future<ResetPasswordForEmailRes> auth.resetPasswordForEmail(String emailOrPhone, {String? redirectTo})

Reset password via email or phone number. After calling, a verification code will be sent. You need to complete password reset through the returned updateUser callback.

Parameters

emailOrPhone
String

Email or phone number

redirectTo
String?

Redirect URL

Response

Future
ResetPasswordForEmailRes

Example

final result = await auth.resetPasswordForEmail('user@example.com');

if (result.error != null) {
print('Failed to send verification code: ${result.error!.message}');
return;
}

// After user receives verification code
final resetResult = await result.data!.updateUser!(
UpdateUserAttributes(nonce: '123456', password: 'newPassword123'),
);

if (resetResult.isSuccess) {
print('Password reset successfully, auto-logged in');
}

resetPasswordForOld

Future<SignInRes> auth.resetPasswordForOld(ResetPasswordForOldReq params)

Reset password with old password.

Parameters

params
ResetPasswordForOldReq

Response

Future
SignInRes

Example

final result = await auth.resetPasswordForOld(
ResetPasswordForOldReq(
oldPassword: 'oldPassword123',
newPassword: 'newPassword456',
),
);

if (result.isSuccess) {
print('Password changed successfully');
} else {
print('Password change failed: ${result.error!.message}');
}

reauthenticate

Future<ReauthenticateRes> auth.reauthenticate();

Re-authenticate. Send verification code to user's email or phone number. After verification, sensitive operations can be performed (such as setting a new password).

Parameters

No parameters

Response

Future
ReauthenticateRes

Example

final result = await auth.reauthenticate();

if (result.error != null) {
print('Failed to send verification code: ${result.error!.message}');
return;
}

final authResult = await result.data!.updateUser!(
UpdateUserAttributes(nonce: '123456', password: 'newSecurePassword'),
);

if (authResult.isSuccess) {
print('Re-authentication successful');
}

Verification Management

getVerification

Future<GetVerificationRes> auth.getVerification(GetVerificationReq params)

Send verification code. Supports sending to email or phone number.

Parameters

params
GetVerificationReq

Response

Future
GetVerificationRes

Example

final result = await auth.getVerification(
GetVerificationReq(email: 'user@example.com'),
);

if (result.isSuccess) {
print('Verification code sent');
} else {
print('Failed to send: ${result.error!.message}');
}

verify

Future<VerifyRes> auth.verify(VerifyReq params)

Verify verification code (for email/phone verification).

Parameters

params
VerifyReq

Response

Future
VerifyRes

Example

final result = await auth.verify(
VerifyReq(
email: 'user@example.com',
token: '123456',
),
);

if (result.isSuccess) {
print('Verification successful');
} else {
print('Verification failed: ${result.error!.message}');
}

verifyOAuth

Future<SignInRes> auth.verifyOAuth(VerifyOAuthReq params)

Verify OAuth callback. Handle the callback after user authorization on third-party platform.

Parameters

params
VerifyOAuthReq

Response

Future
SignInRes

Example

// Handle OAuth callback (typically in web platform)
final result = await auth.verifyOAuth(
VerifyOAuthReq(
code: 'auth-code-from-callback',
state: 'state-from-callback',
),
);

if (result.isSuccess) {
print('OAuth verification successful: ${result.data?.user?.id}');
}

verifyOtp

Future<SignInRes> auth.verifyOtp(VerifyOtpParams params)

Verify OTP (one-time password). Used to verify the verification code sent by signInWithOtp or signUp.

Parameters

params
VerifyOtpParams

Response

Future
SignInRes

Example

final result = await auth.verifyOtp(
VerifyOtpParams(token: '123456'),
);

if (result.isSuccess) {
print('OTP verification successful: ${result.data?.user?.id}');
} else {
print('Verification failed: ${result.error!.message}');
}

resend

Future<ResendRes> auth.resend(ResendReq params)

Resend verification code.

Parameters

params
ResendReq

Response

Future
ResendRes

Example

final result = await auth.resend(
ResendReq(email: 'user@example.com'),
);

if (result.isSuccess) {
print('Verification code resent');
} else {
print('Resend failed: ${result.error!.message}');
}

getCaptchaToken

Future<GetCaptchaTokenRes> auth.getCaptchaToken()

Get CAPTCHA token. Used to get CAPTCHA verification token before sending verification code.

Parameters

No parameters

Response

Future
GetCaptchaTokenRes

Example

final result = await auth.getCaptchaToken();

if (result.isSuccess) {
final captchaToken = result.data?.captchaToken;
print('CAPTCHA token: $captchaToken');
}

createCaptchaData

Future<CreateCaptchaDataRes> auth.createCaptchaData(CreateCaptchaDataReq params)

Create CAPTCHA verification data. Used to initialize CAPTCHA challenge.

Parameters

params
CreateCaptchaDataReq

Response

Future
CreateCaptchaDataRes

Example

final result = await auth.createCaptchaData(
CreateCaptchaDataReq(captchaToken: 'captcha-token'),
);

if (result.isSuccess) {
print('CAPTCHA data created');
}

verifyCaptchaData

Future<VerifyCaptchaDataRes> auth.verifyCaptchaData(VerifyCaptchaDataReq params)

Verify CAPTCHA. Validate user's CAPTCHA response.

Parameters

params
VerifyCaptchaDataReq

Response

Future
VerifyCaptchaDataRes

Example

final result = await auth.verifyCaptchaData(
VerifyCaptchaDataReq(
captchaToken: 'captcha-token',
captchaAnswer: 'user-answer',
),
);

if (result.isSuccess) {
print('CAPTCHA verified successfully');
} else {
print('CAPTCHA verification failed');
}

clearCaptchaToken

Future<ClearCaptchaTokenRes> auth.clearCaptchaToken()

Clear CAPTCHA token. Clean up CAPTCHA state after verification.

Parameters

No parameters

Response

Future
ClearCaptchaTokenRes

Example

final result = await auth.clearCaptchaToken();

if (result.isSuccess) {
print('CAPTCHA token cleared');
}

Document Database

The document database (NoSQL) provides JS SDK-style chained calls, and you get an instance via app.database(). It supports create, read, update, and delete operations on collections and documents, complex conditional queries, aggregation, transactions, and more, and is fully aligned with the HTTP API.

final app = await CloudBase.init(env: 'your-env-id');
final db = app.database();

// Add a single record
final addRes = await db.collection('todos').add({
'title': 'Learn CloudBase',
'completed': false,
'createdAt': DateTime.now(),
});
print('New document ID: ${addRes.id}');

database

CloudBaseDatabase app.database({String? instance, String? database})

Gets a document database instance. The optional parameters instance (instance ID) and database (database name) specify the database to access. Both can be omitted, in which case (default) is used (the default database of the default instance). You only need to pass them explicitly when accessing a non-default instance or database.

Parameters

instance
String?

Instance ID, defaults to (default)

database
String?

Database name, defaults to (default)

Response

CloudBaseDatabase
CloudBaseDatabase

Database instance, providing capabilities such as collection, command, Geo, and startTransaction

Example

final db = app.database();

createCollection

Future<DbCreateCollectionResult> db.createCollection(String collName)

Creates a collection.

Parameters

collName
String

Collection name

Response

Future
DbCreateCollectionResult

Example

final result = await db.createCollection('todos');
if (result.isSuccess) {
print('Collection created successfully');
}

collection

CollectionReference db.collection(String collName)

Gets a collection reference, on which you can chain query methods such as where, orderBy, limit, skip, and field, or call doc, add, get, count, and aggregate.

Parameters

collName
String

Collection name

Response

CollectionReference
CollectionReference

Collection reference

Example

final collection = db.collection('todos');

add

Future<DbAddResult> collection.add(dynamic data)

Adds records to a collection, supporting single (Map) and batch (List) additions.

Parameters

data
dynamic

Document data. Pass a Map for a single addition, or a List for batch addition

Response

Future
DbAddResult

Example

final res = await db.collection('todos').add({
'title': 'Learn CloudBase',
'completed': false,
'createdAt': DateTime.now(),
});
print('New document ID: ${res.id}');

doc

DocumentReference collection.doc(dynamic docId)

Gets a document reference, on which you can call get, update, set, remove, and field.

Parameters

docId
dynamic

Document ID

Response

DocumentReference
DocumentReference

Document reference

Example

final docRef = db.collection('todos').doc('doc-id');
final res = await docRef.get();
print(res.data);

where

Query collection.where(Map<String, dynamic> condition)

Sets query conditions, supporting equality matching and complex condition filtering via db.command operators.

Parameters

condition
Map<String, dynamic>

Query condition object, supporting equality matching, operator matching, nested field matching, and more

Response

Query
Query

Query object, on which you can chain methods such as orderBy, limit, skip, field, get, count, update, and remove

Example

final res = await db
.collection('todos')
.where({'completed': false, 'priority': 'high'})
.get();

print('Query results: ${res.data}');

orderBy

Query collection.orderBy(String field, OrderDirection direction)

Sets the sort rule. direction can be OrderDirection.asc or OrderDirection.desc. You can call it multiple times to combine multi-field sorting.

Parameters

field
String

Sort field

direction
OrderDirection

Sort direction: OrderDirection.asc (ascending) or OrderDirection.desc (descending)

Response

Query
Query

Query object, on which you can continue chaining

Example

final res = await db
.collection('todos')
.orderBy('createdAt', OrderDirection.desc)
.get();

limit

Query collection.limit(int max)

Sets the maximum number of records to return.

Parameters

max
int

Maximum number of records to return

Response

Query
Query

Query object, on which you can continue chaining

Example

final res = await db.collection('todos').limit(10).get();

skip

Query collection.skip(int offset)

Sets the number of records to skip, commonly used for pagination.

Parameters

offset
int

Number of records to skip (offset)

Response

Query
Query

Query object, on which you can continue chaining

Example

const pageSize = 10;
const pageNum = 2;

final res = await db
.collection('todos')
.orderBy('createdAt', OrderDirection.desc)
.skip((pageNum - 1) * pageSize)
.limit(pageSize)
.get();

print('Page $pageNum data: ${res.data}');
print('Offset: ${res.offset}, page size: ${res.limit}');

field

Query collection.field(Map<String, dynamic> projection)

Specifies the fields to return in the query. true means return, and false means do not return. The document reference doc also supports the field method.

Parameters

projection
Map<String, dynamic>

Field projection, e.g. {'title': true, 'content': false}

Response

Query
Query

Query object, on which you can continue chaining

Example

final res = await db
.collection('todos')
.where({'completed': false})
.field({'title': true, 'completed': true, 'content': false})
.get();

get

Future<DbGetResult> collection.get()
Future<DbGetResult> query.get()
Future<DbGetResult> doc.get()

Gets query results. Called on a collection reference, it performs an unconditional query; called on a Query, it returns the list of matching documents; called on a document reference, it returns a single document (data is an empty list when the document does not exist).

Parameters

No parameters

Response

Future
DbGetResult

Example

final res = await db.collection('todos').get();
print('${res.data.length} records in total');

count

Future<DbCountResult> collection.count()
Future<DbCountResult> query.count()

Counts the number of documents matching the conditions.

Parameters

No parameters

Response

Future
DbCountResult

Example

final res = await db
.collection('todos')
.where({'completed': false})
.count();
print('Number of incomplete tasks: ${res.total}');

update

Future<DbUpdateResult> query.update(Map<String, dynamic> data)
Future<DbUpdateResult> doc.update(Map<String, dynamic> data, {bool returnDoc = false})

Updates documents. Called on a Query, it batch-updates documents matching the conditions; called on a document reference, it performs a merge update on a single document, and returns the updated document when returnDoc is true.

Parameters

data
Map<String, dynamic>

Update data. You can use db.command update operators (such as _.inc, _.set, _.push, etc.)

returnDoc
bool

Supported only by document reference update. When true, returns the updated document. Defaults to false

Response

Future
DbUpdateResult

Example

final _ = db.command;

final res = await db
.collection('todos')
.doc('doc-id')
.update({'count': _.inc(1), 'completed': true}, returnDoc: true);
print('Updated document: ${res.doc}');

set

Future<DbUpdateResult> doc.set(Map<String, dynamic> data)

Sets document data (full replacement; creates the document if it does not exist).

Parameters

data
Map<String, dynamic>

Full document data, which will completely replace the original document

Response

Future
DbUpdateResult

Example

final res = await db.collection('todos').doc('doc-id').set({
'title': 'Reset task',
'completed': false,
});

remove

Future<DbRemoveResult> query.remove()
Future<DbRemoveResult> doc.remove()

Deletes documents. Called on a Query, it batch-deletes documents matching the conditions; called on a document reference, it deletes a single document.

Parameters

No parameters

Response

Future
DbRemoveResult

Example

final res = await db.collection('todos').doc('doc-id').remove();
print('${res.deleted} records deleted');

command

DbCommand get db.command

Gets the query/update command (corresponding to the JS SDK's db.command, commonly abbreviated as _). It supports comparison, logical, field/array, update, geolocation, and other operators.

Parameters

No parameters

Response

DbCommand
DbCommand

Command object, used to build query conditions and update operations

Example

final _ = db.command;

// eq / neq / gt / gte / lt / lte / inList / nin
await db.collection('todos').where({'age': _.gte(18)}).get();

// and / or / not / nor
await db.collection('todos').where({
'priority': _.or([_.eq('high'), _.eq('medium')]),
}).get();

aggregate

Aggregate collection.aggregate()

Gets an aggregation operation object. Chain aggregation stages and then call end() to execute. Supports match, group, sort, project, limit, skip, unwind, lookup, addFields, count, sample, bucket, bucketAuto, geoNear, replaceRoot, sortByCount, and custom stage.

Parameters

No parameters

Response

Aggregate
Aggregate

Aggregation operation object. Chain stages and then call end() to execute

Example

final res = await db
.collection('todos')
.aggregate()
.match({'completed': true})
.group({
'_id': '\$priority',
'total': {'\$sum': 1},
})
.sort({'total': -1})
.end();

print('Aggregation results: ${res.data}');

startTransaction

Future<Transaction> db.startTransaction()

Starts a transaction and returns a transaction object. Use the transaction object's collection to get a collection reference within the transaction to operate on, and finally call commit to commit or rollback to roll back.

Parameters

No parameters

Response

Future
Transaction

Example

final _ = db.command;

final transaction = await db.startTransaction();
try {
await transaction.collection('accounts').doc('a').update({'balance': _.inc(-100)});
await transaction.collection('accounts').doc('b').update({'balance': _.inc(100)});
await transaction.commit();
} catch (e) {
await transaction.rollback();
}

runCommands

Future<DbRunCommandsResult> db.runCommands({required List<Map<String, dynamic>> commands, String? transactionId})

Executes MongoDB-style database commands (in batch). Callable by administrators only.

Parameters

commands
List<Map<String, dynamic>>

Array of command objects

transactionId
String?

Transaction ID (optional, executes all commands within the transaction)

Response

Future
DbRunCommandsResult

Example

final res = await db.runCommands(commands: [
{'find': 'todos', 'filter': {'completed': true}},
]);
print('Execution results: ${res.list}');

Geo

GeoNamespace get db.Geo
DbRegExp db.RegExp({required String regexp, String? options})
DbServerDate db.serverDate({int offset = 0})

Database helper types: the geolocation namespace Geo, the regular expression RegExp, and the server-side time serverDate.

  • Geo supports point, lineString, polygon, multiPoint, multiLineString, and multiPolygon, used together with the operators geoNear, geoWithin, and geoIntersects.
  • RegExp is used for fuzzy queries; options such as i means case-insensitive.
  • serverDate generates server-side time, where offset is the offset in milliseconds.

Parameters

No parameters

Response

GeoNamespace
GeoNamespace

Geolocation namespace

Example

final _ = db.command;

// Query records within 5000 meters of the specified coordinates
final res = await db.collection('places').where({
'location': _.geoNear(
geometry: db.Geo.point(116.397, 39.908),
maxDistance: 5000,
),
}).get();

Data Model

getById

Future<GetByIdRes> app.data.model(collectionName).getById(String id)

Get a single record by ID.

Parameters

id
String

Record ID

Response

Future
GetByIdRes

Example

final result = await app.data.model('users').getById('record-id-123');

if (result.isSuccess) {
final record = result.data?.record;
print('Record: ${record?.toJson()}');
} else {
print('Failed to get record: ${result.error!.message}');
}

get

Future<GetRes> app.data.model(collectionName).get([GetReq? params])

Query records with filters. Supports WHERE conditions, sorting, pagination, etc.

Parameters

params
GetReq?

Query parameters (optional)

Response

Future
GetRes

Example

final result = await app.data.model('users').get(
GetReq(
filter: 'age > 18',
sort: ['-createdAt'],
limit: 10,
),
);

if (result.isSuccess) {
for (final record in result.data?.records ?? []) {
print('User: ${record.toJson()}');
}
}

list

Future<ModelFindManyResponse> app.models.list({
required String modelName,
Map<String, dynamic>? filter,
Map<String, dynamic>? select,
int? pageSize,
int? pageNumber,
bool? getCount,
List<Map<String, String>>? orderBy,
})

Query multiple records. Supports filter conditions, field selection, pagination, and sorting.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>?

Filter condition, format: {'where': {'field': {'\$eq': 'value'}}}

select
Map<String, dynamic>?

Field selection, format: {'\$master': true} or {'field': true}

pageSize
int?

Page size, default 10

pageNumber
int?

Page number, default 1

getCount
bool?

Whether to return total count

orderBy
List<Map<String, String>>?

Sorting, up to 3 fields, format: [{'field': 'desc'}]

Response

Future
ModelFindManyResponse

Example

final result = await app.models.list(
modelName: 'user',
pageSize: 10,
pageNumber: 1,
getCount: true,
orderBy: [{'createdAt': 'desc'}],
filter: {'where': {'age': {'\$gt': 18}}},
);

if (result.isSuccess) {
print('Total: ${result.total}');
for (final record in result.records) {
print('Record: $record');
}
}

listSimple

Future<ModelFindManyResponse> app.models.listSimple({required String modelName, int? pageSize, int? pageNumber, bool? getCount})

Simple query for multiple records (GET request, only supports pagination parameters).

Parameters

modelName
String

Data model identifier

pageSize
int?

Page size

pageNumber
int?

Page number, default 1

getCount
bool?

Whether to return total count, default false

Response

Future
ModelFindManyResponse

Example

final result = await app.models.listSimple(
modelName: 'user',
pageSize: 10,
pageNumber: 1,
getCount: true,
);

if (result.isSuccess) {
print('Total: ${result.total}');
for (final record in result.records) {
print('Record: $record');
}
}

create

Future<ModelCreateResponse> app.models.create({required String modelName, required Map<String, dynamic> data})

Create a single record.

Parameters

modelName
String

Data model identifier

data
Map<String, dynamic>

Record data

Response

Future
ModelCreateResponse

Example

final result = await app.models.create(
modelName: 'user',
data: {'name': 'Zhang San', 'age': 25, 'email': 'test@example.com'},
);

if (result.isSuccess) {
print('Created successfully, ID: ${result.id}');
} else {
print('Creation failed: ${result.message}');
}

createMany

Future<ModelCreateManyResponse> app.models.createMany({required String modelName, required List<Map<String, dynamic>> data})

Batch create records.

Parameters

modelName
String

Data model identifier

data
List<Map<String, dynamic>>

List of records to create

Response

Future
ModelCreateManyResponse

Example

final result = await app.models.createMany(
modelName: 'user',
data: [
{'name': 'Zhang San', 'age': 25},
{'name': 'Li Si', 'age': 30},
],
);

if (result.isSuccess) {
print('Batch creation successful, ID list: ${result.idList}');
}

update

Future<ModelUpdateDeleteResponse> app.models.update({required String modelName, required Map<String, dynamic> filter, required Map<String, dynamic> data})

Update a single record.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>

Filter condition

data
Map<String, dynamic>

Data to update

Response

Future
ModelUpdateDeleteResponse

Example

final result = await app.models.update(
modelName: 'user',
filter: {'where': {'_id': {'\$eq': '123'}}},
data: {'age': 26},
);

if (result.isSuccess) {
print('Update successful, ${result.count} record(s) updated');
}

updateMany

Future<ModelUpdateDeleteManyResponse> app.models.updateMany({required String modelName, required Map<String, dynamic> filter, required Map<String, dynamic> data})

Batch update records.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>

Filter condition

data
Map<String, dynamic>

Data to update

Response

Future
ModelUpdateDeleteManyResponse

Example

final result = await app.models.updateMany(
modelName: 'user',
filter: {'where': {'age': {'\$lt': 18}}},
data: {'status': 'minor'},
);

if (result.isSuccess) {
print('Batch update successful, ${result.count} record(s) updated');
}

upsert

Future<ModelUpsertResponse> app.models.upsert({required String modelName, required Map<String, dynamic> filter, Map<String, dynamic>? create, Map<String, dynamic>? update})

Create or update a single record (Upsert). If a matching record is found, it will be updated; otherwise, a new record will be created.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>

Filter condition

create
Map<String, dynamic>?

Data to create when record does not exist

update
Map<String, dynamic>?

Data to update when record already exists

Response

Future
ModelUpsertResponse

Example

final result = await app.models.upsert(
modelName: 'user',
filter: {'where': {'email': {'\$eq': 'test@example.com'}}},
create: {'name': 'Zhang San', 'email': 'test@example.com', 'age': 25},
update: {'age': 26},
);

if (result.isSuccess) {
print('Upsert successful, ${result.count} record(s) changed');
if (result.id != null) {
print('New record ID: ${result.id}');
}
}

deleteById

Future<ModelUpdateDeleteResponse> app.models.deleteById({required String modelName, required String recordId})

Delete a single record by ID.

Parameters

modelName
String

Data model identifier

recordId
String

Record ID

Response

Future
ModelUpdateDeleteResponse

Example

final result = await app.models.deleteById(
modelName: 'user',
recordId: '123',
);

if (result.isSuccess) {
print('Deletion successful, ${result.count} record(s) changed');
}

deleteRecord

Future<ModelUpdateDeleteResponse> app.models.deleteRecord({required String modelName, required Map<String, dynamic> filter})

Delete a single record by condition.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>

Filter condition

Response

Future
ModelUpdateDeleteResponse

Example

final result = await app.models.deleteRecord(
modelName: 'user',
filter: {'where': {'_id': {'\$eq': '123'}}},
);

if (result.isSuccess) {
print('Deletion successful, ${result.count} record(s) changed');
}

deleteMany

Future<ModelUpdateDeleteManyResponse> app.models.deleteMany({required String modelName, required Map<String, dynamic> filter})

Batch delete records.

Parameters

modelName
String

Data model identifier

filter
Map<String, dynamic>

Filter condition

Response

Future
ModelUpdateDeleteManyResponse

Example

final result = await app.models.deleteMany(
modelName: 'user',
filter: {'where': {'status': {'\$eq': 'inactive'}}},
);

if (result.isSuccess) {
print('Batch deletion successful, ${result.count} record(s) changed');
}

mysqlCommand

Future<ModelMysqlCommandResponse> app.models.mysqlCommand({required String sqlTemplate, List<ModelMysqlParameter>? parameter, ModelMysqlConfig? config})

Execute MySQL commands. Supports parameterized queries.

Parameters

sqlTemplate
String

SQL statement, supports parameter placeholders {{ var }}

parameter
List<ModelMysqlParameter>?

SQL parameter list

config
ModelMysqlConfig?

Execution config (timeout, preparedStatements, dbLinkName)

Response

Future
ModelMysqlCommandResponse

Example

final result = await app.models.mysqlCommand(
sqlTemplate: 'select * from `users` where _id = {{ _id }}',
parameter: [
ModelMysqlParameter(key: '_id', type: 'STRING', value: '123'),
],
);

if (result.isSuccess) {
print('Execution result: ${result.executeResultList}');
}

Data Source Queries

getAggregateDataSourceList

Future<AggregateDataSourceListResponse> app.models.getAggregateDataSourceList({
List<String>? idList,
List<String>? nameList,
int? pageSize,
int? pageNumber,
bool? getCount,
List<Map<String, String>>? orderBy,
})

Query aggregate data source list (GET request, supports pagination and sorting).

Parameters

idList
List<String>?

Data source ID list

nameList
List<String>?

Data source name list

pageSize
int?

Page size, default 10

pageNumber
int?

Page number, default 1

getCount
bool?

Whether to return total count

orderBy
List<Map<String, String>>?

Sorting, format: [{'field': 'desc'}]

Response

Future
AggregateDataSourceListResponse

Example

final result = await app.models.getAggregateDataSourceList(
pageSize: 10,
pageNumber: 1,
getCount: true,
);

if (result.isSuccess) {
print('Total: ${result.count}');
for (final ds in result.rows) {
print('${ds.name}: ${ds.title} (type: ${ds.type})');
}
}

getDataSourceAggregateDetail

Future<DataSourceAggregateDetailResponse> app.models.getDataSourceAggregateDetail({
String? datasourceId,
String? dataSourceName,
String? viewId,
int? queryPublish,
bool? queryModelRelation,
String? dbInstanceType,
String? databaseTableName,
})

Query aggregate data source detail by conditions. datasourceId and dataSourceName cannot both be empty.

Parameters

datasourceId
String?

Data source ID (cannot both be empty with dataSourceName)

dataSourceName
String?

Data source name (cannot both be empty with datasourceId)

viewId
String?

View ID

queryPublish
int?

Query published data source (0: preview, 1: published)

queryModelRelation
bool?

Whether to query relation

dbInstanceType
String?

DB instance type

databaseTableName
String?

Database table name

Response

Future
DataSourceAggregateDetailResponse

Example

final result = await app.models.getDataSourceAggregateDetail(
dataSourceName: 'user',
);

if (result.isSuccess) {
print('Schema: ${result.dataSource?.schema}');
print('Name: ${result.dataSource?.title}');
}

getDataSourceByTableName

Future<DataSourceByTableNameResponse> app.models.getDataSourceByTableName({required List<String> tableNames})

Query data source schema definition by database table name.

Parameters

tableNames
List<String>

Database table name list

Response

Future
DataSourceByTableNameResponse

Example

final result = await app.models.getDataSourceByTableName(
tableNames: ['user_table', 'order_table'],
);

if (result.isSuccess) {
for (final info in result.dataSourceTableInfos) {
print('Table: ${info.tableName}, Data source: ${info.name}');
}
}

getBasicDataSourceList

Future<BasicDataSourceListResponse> app.models.getBasicDataSourceList({
List<String>? idList,
List<String>? nameList,
int? pageNum,
int? pageSize,
bool? queryAll,
List<DataSourceQueryFilter>? queryFilterList,
bool? onlyFlexDb,
})

Query basic data source list by conditions (POST request, supports filter conditions).

Parameters

idList
List<String>?

Data source ID list

nameList
List<String>?

Data source name list

pageNum
int?

Page number, default 1

pageSize
int?

Page size, default 10

queryAll
bool?

Whether to query all

queryFilterList
List<DataSourceQueryFilter>?

Query filter list

onlyFlexDb
bool?

Whether to query only flexdb type

Response

Future
BasicDataSourceListResponse

Example

final result = await app.models.getBasicDataSourceList(
pageSize: 10,
pageNum: 1,
queryFilterList: [
DataSourceQueryFilter(name: 'Type', values: ['database']),
],
);

if (result.isSuccess) {
print('Total: ${result.total}');
for (final ds in result.dataSourceList) {
print('${ds.name}: ${ds.title}');
}
}

getBasicDataSource

Future<BasicDataSourceResponse> app.models.getBasicDataSource({
String? datasourceId,
String? dataSourceName,
String? viewId,
int? queryPublish,
bool? queryModelRelation,
String? dbInstanceType,
String? databaseTableName,
})

Query basic data source info by conditions. datasourceId and dataSourceName cannot both be empty.

Parameters

datasourceId
String?

Data source ID (cannot both be empty with dataSourceName)

dataSourceName
String?

Data source name (cannot both be empty with datasourceId)

viewId
String?

View ID

queryPublish
int?

Query published data source (0: preview, 1: published)

queryModelRelation
bool?

Whether to query relation

dbInstanceType
String?

DB instance type

databaseTableName
String?

Database table name

Response

Future
BasicDataSourceResponse

Example

final result = await app.models.getBasicDataSource(
dataSourceName: 'user',
);

if (result.isSuccess) {
print('Data source: ${result.dataSource?.name}');
print('Type: ${result.dataSource?.type}');
}

getSchemaList

Future<DataSourceSchemaListResponse> app.models.getSchemaList({List<String>? dataSourceNameList})

Query all data source schemas in the environment. If no parameters are provided, all schemas are returned.

Parameters

dataSourceNameList
List<String>?

Data source name list (optional, query all if not provided)

Response

Future
DataSourceSchemaListResponse

Example

final result = await app.models.getSchemaList(
dataSourceNameList: ['user', 'order'],
);

if (result.isSuccess) {
for (final rel in result.dataSourceRelationInfoList) {
print('${rel.name}: ${rel.title}');
}
}

getTableName

Future<DataSourceTableNameResponse> app.models.getTableName({String? dataSourceName})

Query the corresponding database table name by data source name.

Parameters

dataSourceName
String?

Data source name

Response

Future
DataSourceTableNameResponse

Example

final result = await app.models.getTableName(
dataSourceName: 'user',
);

if (result.isSuccess) {
print('Table name: ${result.tableName}');
print('Database type: ${result.dbType}');
}

MySQL Database

query

Future<MySqlResponse> app.mysql.query({required String table, String? schema, String? instance, MySqlQueryOptions? options})

Query MySQL data. Supports field selection, pagination, sorting, and filter conditions.

Supported filter operators: eq (equal), neq (not equal), gt (greater than), gte (greater than or equal), lt (less than), lte (less than or equal), like (fuzzy match), in (in list), is (null check)

Parameters

table
String

Table name

schema
String?

Database name

instance
String?

Database instance identifier (requires schema)

options
MySqlQueryOptions?

Query options

Response

Future
MySqlResponse

Example

final result = await app.mysql.query(
table: 'users',
options: MySqlQueryOptions(
select: '*',
limit: 10,
offset: 0,
order: 'id.asc',
withCount: true,
),
);

if (result.isSuccess) {
print('Total: ${result.total}');
for (final row in result.data) {
print('Record: $row');
}
}

insert

Future<MySqlWriteResponse> app.mysql.insert({required String table, required dynamic data, String? schema, String? instance, bool? upsert, String? onConflict})

Insert data. Supports single and batch insert, as well as Upsert mode.

Parameters

table
String

Table name

data
dynamic

Insert data, single Map or batch List<Map>

schema
String?

Database name

instance
String?

Database instance identifier

upsert
bool?

Whether to enable Upsert mode (default false)

onConflict
String?

Upsert conflict field

Response

Future
MySqlWriteResponse

Example

final result = await app.mysql.insert(
table: 'users',
data: {'name': 'Zhang San', 'age': 25},
);

if (result.isSuccess) {
print('Insert successful');
}

update (MySQL)

Future<MySqlWriteResponse> app.mysql.update({required String table, required Map<String, dynamic> data, required Map<String, String> filters, String? schema, String? instance})

Update MySQL data. WHERE condition is required.

Parameters

table
String

Table name

data
Map<String, dynamic>

Data to update

filters
Map<String, String>

WHERE condition (cannot be empty)

schema
String?

Database name

instance
String?

Database instance identifier

Response

Future
MySqlWriteResponse

Example

final result = await app.mysql.update(
table: 'users',
data: {'age': 26},
filters: {'name': 'eq.Zhang San'},
);

if (result.isSuccess) {
print('Update successful');
} else {
print('Update failed: ${result.message}');
}

delete (MySQL)

Future<MySqlWriteResponse> app.mysql.delete({required String table, required Map<String, String> filters, String? schema, String? instance})

Delete MySQL data. WHERE condition is required.

Parameters

table
String

Table name

filters
Map<String, String>

WHERE condition (cannot be empty)

schema
String?

Database name

instance
String?

Database instance identifier

Response

Future
MySqlWriteResponse

Example

final result = await app.mysql.delete(
table: 'users',
filters: {'name': 'eq.Zhang San'},
);

if (result.isSuccess) {
print('Delete successful');
}

count

Future<MySqlCountResponse> app.mysql.count({required String table, Map<String, String>? filters, String? schema, String? instance})

Count MySQL data records.

Parameters

table
String

Table name

filters
Map<String, String>?

Filter conditions

schema
String?

Database name

instance
String?

Database instance identifier

Response

Future
MySqlCountResponse

Example

final result = await app.mysql.count(
table: 'users',
filters: {'age': 'gt.18'},
);

if (result.isSuccess) {
print('Matching records: ${result.count}');
} else {
print('Count failed: ${result.message}');
}

Cloud Functions

callFunction

Future<FunctionResponse> app.callFunction({
required String name,
FunctionType? type,
Map<String, dynamic>? data,
HttpMethod? method,
String? path,
Map<String, String>? header,
bool? parse,
})

Call cloud function. Supports both basic cloud functions and function-type cloud run.

Parameters

name
String

Function/service name

type
FunctionType?

Call type: FunctionType.function (default) / FunctionType.cloudrun

data
Map<String, dynamic>?

Request data

method
HttpMethod?

HTTP method (only valid for cloudrun type, default POST)

path
String?

HTTP path (only valid for cloudrun type, default /)

header
Map<String, String>?

HTTP headers (only valid for cloudrun type)

parse
bool?

Whether to parse return object (only valid for function type, default true)

Response

Future
FunctionResponse

Example

final result = await app.callFunction(
name: 'myFunction',
data: {'action': 'getUserList', 'pageSize': 10},
);

if (result.isSuccess) {
print('Execution result: ${result.result}');
} else {
print('Execution failed: ${result.message}');
}

Cloud Run

callContainer

Future<CloudRunResponse> app.callContainer({
required String name,
HttpMethod? method,
String? path,
Map<String, String>? header,
Map<String, dynamic>? data,
})

Call cloud run container service. Supports custom HTTP method, path, and headers.

Parameters

name
String

Cloud run service name

method
HttpMethod?

HTTP request method (default GET)

path
String?

HTTP request path (default /)

header
Map<String, String>?

HTTP request headers

data
Map<String, dynamic>?

HTTP request body

Response

Future
CloudRunResponse

Example

final result = await app.callContainer(
name: 'my-service',
method: HttpMethod.post,
path: '/api/data',
data: {'key': 'value'},
header: {'X-Custom': 'header'},
);

if (result.isSuccess) {
print('Response data: ${result.result}');
} else {
print('Request failed: ${result.message}');
}

APIs

apis[name]

ApiMethodProxy app.apis[String apiName]

Call API gateway interface. Supports accessing API proxy objects via subscript operator for chained calls. Supports GET, POST, PUT, DELETE, HEAD, OPTIONS, PATCH methods.

Parameters

apiName
String

API name

Response

ApiMethodProxy
ApiMethodProxy

API method proxy object, supports chained calls

ApiResponse
ApiResponse

API response

Example

// POST request
final result = await app.apis['myApi'].post(
path: '/users',
body: {'name': 'Zhang San', 'age': 25},
);

if (result.isSuccess) {
print('Response data: ${result.data}');
}

// GET request
final getResult = await app.apis['myApi'].get(path: '/users/123');

// PUT request
final putResult = await app.apis['myApi'].put(
path: '/users/123',
body: {'name': 'Li Si'},
);

// DELETE request
final deleteResult = await app.apis['myApi'].delete(path: '/users/123');

Cloud Storage

Cloud Storage module provides file upload, download, delete, copy, move and other operations.

Initialization

final app = await CloudBase.init(
env: 'your-env-id',
accessKey: 'your-access-key',
);

final storage = app.storage.from();

upload

Future<StorageResponse<StorageUploadResult>> storage.upload(
String path,
List<int> fileData, {
StorageUploadOptions? options,
})

Upload file to cloud storage. This method will first get upload info, then upload file to COS, and finally return fileID.

Parameters

path
String

Cloud storage relative path, e.g. `images/photo.jpg`.

fileData
List<int>

File byte data.

options
StorageUploadOptions

Upload options.

Response

data
Object

Return data

error
StorageError?

Error message.

Example

import 'package:cloudbase_flutter/cloudbase_flutter.dart';
import 'package:image_picker/image_picker.dart';

final app = await CloudBase.init(
env: 'your-env-id',
accessKey: 'your-access-key',
);

final storage = app.storage.from();

// Pick image and upload
Future<void> uploadImage() async {
final picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);

if (image == null) return;

final fileBytes = await image.readAsBytes();

final result = await storage.upload(
'images/${image.name}',
fileBytes,
StorageUploadOptions(
contentType: 'image/jpeg',
cacheControl: 'max-age=3600',
),
);

if (result.isSuccess) {
print('Upload successful: ${result.data?.id}');
print('File path: ${result.data?.path}');
} else {
print('Upload failed: ${result.error?.message}');
}
}

getUploadInfo

Future<StorageResponse<List<StorageUploadInfo>>> storage.getUploadInfo(
List<String> paths,
)

Get file upload info. Returns upload URL and other info for client to directly upload files to COS.

Parameters

paths
List<String>

File path list (cloud storage relative path).

Response

data
List<StorageUploadInfo>?

Upload info list.

error
StorageError?

Error message.

Example

final result = await storage.getUploadInfo([
'images/photo.jpg',
'documents/report.pdf',
]);

if (result.isSuccess) {
for (final info in result.data!) {
print('Path: ${info.path}');
print('Upload URL: ${info.uploadUrl}');
print('File ID: ${info.fileId}');
}
}

getDownloadUrls

Future<StorageResponse<List<StorageDownloadInfo>>> storage.getDownloadUrls(
List<String> fileIds, {
int? expiresIn,
})

Get file download URLs.

Parameters

fileIds
List<String>

File ID list (full cloudObjectId, e.g. `cloud://envId.xxx/path/file.jpg`).

expiresIn
int?

Reserved parameter, current API does not support custom expiration time.

Response

data
List<StorageDownloadInfo>?

Download info list.

error
StorageError?

Error message.

Example

final result = await storage.getDownloadUrls([
'cloud://envId.xxx/images/photo.jpg',
'cloud://envId.xxx/documents/report.pdf',
]);

if (result.isSuccess) {
for (final info in result.data!) {
if (info.isSuccess) {
print('Download URL: ${info.downloadUrl}');
} else {
print('Failed to get: ${info.message}');
}
}
}

createSignedUrl

Future<StorageResponse<String>> storage.createSignedUrl(
String fileId,
int expiresIn,
)

Create signed URL (temporary access link).

Parameters

fileId
String

Full fileID.

expiresIn
int

Expiration time (seconds).

Response

data
String?

Signed URL.

error
StorageError?

Error message.

Example

final result = await storage.createSignedUrl(
'cloud://envId.xxx/images/photo.jpg',
3600, // 1 hour expiration
);

if (result.isSuccess) {
print('Signed URL: ${result.data}');
}

createSignedUrls

Future<StorageResponse<List<StorageDownloadInfo>>> storage.createSignedUrls(
List<String> fileIds,
int expiresIn,
)

Batch create signed URLs.

Parameters

fileIds
List<String>

Full fileID list.

expiresIn
int

Expiration time (seconds).

Response

data
List<StorageDownloadInfo>?

Download info list.

error
StorageError?

Error message.

Example

final result = await storage.createSignedUrls(
[
'cloud://envId.xxx/images/photo1.jpg',
'cloud://envId.xxx/images/photo2.jpg',
],
3600,
);

if (result.isSuccess) {
for (final info in result.data!) {
print('${info.fileId}: ${info.downloadUrl}');
}
}

remove

Future<StorageResponse<List<StorageDeleteResult>>> storage.remove(
List<String> fileIds,
)

Delete files.

Parameters

fileIds
List<String>

File ID list to delete (full fileID).

Response

data
List<StorageDeleteResult>?

Delete result list.

error
StorageError?

Error message.

Example

final result = await storage.remove([
'cloud://envId.xxx/images/photo.jpg',
'cloud://envId.xxx/documents/report.pdf',
]);

if (result.isSuccess) {
for (final item in result.data!) {
if (item.isSuccess) {
print('Delete successful: ${item.fileId}');
} else {
print('Delete failed: ${item.fileId} - ${item.message}');
}
}
}

copy

Future<StorageResponse<StorageCopyResult>> storage.copy(
String fromPath,
String toPath, {
bool overwrite = true,
})

Copy file.

Parameters

fromPath
String

Source file path (relative path).

toPath
String

Target file path (relative path).

overwrite
bool

Whether to overwrite if target exists, default `true`.

Response

data
StorageCopyResult?

Copy result.

error
StorageError?

Error message.

Example

final result = await storage.copy(
'images/photo.jpg',
'images/backup/photo.jpg',
);

if (result.isSuccess) {
print('Copy successful: ${result.data?.cloudObjectId}');
} else {
print('Copy failed: ${result.error?.message}');
}

copyBatch

Future<StorageResponse<List<StorageCopyResult>>> storage.copyBatch(
List<Map<String, dynamic>> items,
)

Batch copy files.

Parameters

items
List<Map<String, dynamic>>

Copy item list, each item contains `srcPath` and `dstPath`.

Response

data
List<StorageCopyResult>?

Copy result list.

error
StorageError?

Error message.

Example

final result = await storage.copyBatch([
{'srcPath': 'images/photo1.jpg', 'dstPath': 'backup/photo1.jpg'},
{'srcPath': 'images/photo2.jpg', 'dstPath': 'backup/photo2.jpg'},
]);

if (result.isSuccess) {
for (final item in result.data!) {
if (item.isSuccess) {
print('Copy successful: ${item.cloudObjectId}');
}
}
}

move

Future<StorageResponse<StorageCopyResult>> storage.move(
String fromPath,
String toPath, {
bool overwrite = true,
})

Move file (implemented by copy + removeOriginal).

Parameters

fromPath
String

Source file path (relative path).

toPath
String

Target file path (relative path).

overwrite
bool

Whether to overwrite if target exists, default `true`.

Response

data
StorageCopyResult?

Move result.

error
StorageError?

Error message.

Example

final result = await storage.move(
'images/old.jpg',
'images/new.jpg',
);

if (result.isSuccess) {
print('Move successful: ${result.data?.cloudObjectId}');
} else {
print('Move failed: ${result.error?.message}');
}

StorageUploadOptions

Upload options:

ParameterTypeDescription
cacheControlString?Cache control, e.g. max-age=3600
contentTypeString?File MIME type, e.g. image/jpeg
metadataMap<String, dynamic>?Custom metadata
upsertboolWhether to overwrite existing file, default true

StorageUploadResult

Upload result:

ParameterTypeDescription
idString?CloudBase fileID
pathString?Upload path
fullPathString?File full path

StorageUploadInfo

Upload info:

ParameterTypeDescription
pathString?File path
uploadUrlString?Upload URL
tokenString?Upload token
authorizationString?Upload authorization
fileIdString?File ID
cosFileIdString?COS file ID
codeString?Error code
messageString?Error message

StorageDownloadInfo

Download info:

ParameterTypeDescription
fileIdString?File ID
downloadUrlString?Download URL
codeString?Error code (on partial failure)
messageString?Error message (on partial failure)

StorageDeleteResult

Delete result:

ParameterTypeDescription
fileIdString?File ID
codeString?Error code (on partial failure)
messageString?Error message (on partial failure)

StorageCopyResult

Copy result:

ParameterTypeDescription
cloudObjectIdString?Cloud file ID of copied object
codeString?Error code (on partial failure)
messageString?Error message (on partial failure)

StorageResponse<T>

Storage response:

ParameterTypeDescription
dataT?Response data
errorStorageError?Error message

StorageError

Storage error:

ParameterTypeDescription
codeString?Error code
messageString?Error message
requestIdString?Request ID

Changelog

1.2.0 (2026-07-24)

  • Add NoSQL Database module (CloudBaseDatabase) with JS-SDK-style chainable API
    • db.collection().doc() document references
    • Chainable query: where / orderBy / limit / skip / field
    • CRUD: add (single & batch), get, count, update, set, remove
    • Query/update commands via db.command: comparison (eq/gt/gte/lt/lte/neq/in/nin), logic (and/or/not/nor), update operators (set/inc/mul/remove/push/pull/pop/shift/unshift/addToSet/rename/max/min)
    • Aggregation pipeline via collection().aggregate()...end()
    • Transactions via db.startTransaction() with commit / rollback
    • Geo types (GeoPoint/GeoLineString/GeoPolygon/GeoMultiPoint/GeoMultiLineString/GeoMultiPolygon) and geo queries
    • RegExp, serverDate helpers and automatic EJSON encode/decode (e.g. DateTime)
    • MongoDB-style commands via runCommands

1.1.0 (2026-07-01)

  • Add Cloud Storage module (CloudBaseStorage)
    • Upload files to cloud storage with upload info and direct COS upload
    • Get signed download URLs (single and batch)
    • Delete files (batch)
    • Copy files (single and batch)
    • Move/rename files
    • Get upload info for client-side direct upload

1.0.9 (2026-06-30)

  • Add X-SDK-Version header (@cloudbase/flutter-sdk/<version>) to all HTTP requests for platform identification
  • Add version management tooling (tool/update_version.dart) to auto-sync version from pubspec.yaml
  • Add CONTRIBUTING.md with release workflow documentation
  • Improve HTTP client to support List request body (for storage APIs)

1.0.8 (2026-05-06)

  • Fix UserProfile.toUser() incorrectly falling back to username (phone number) when email is null, which caused reauthentication to send an invalid email format to the server
  • Fix reauthenticate() to properly distinguish between empty string and valid email, ensuring phone-only users use phone number for verification instead of invalid email

1.0.7 (2026-03-11)

  • Add shouldCreateUser option to signInWithOtp for auto-registration when user does not exist
  • Refactor internal signup logic into reusable _signUpAndSaveSession method

1.0.6 (2026-03-05)

  • Add MySQL module (CloudBaseMySQL)
    • Direct SQL query execution
    • Transaction support (begin, commit, rollback)
    • Database/table management operations
  • Add example code for MySQL modules
  • Add unit tests for MySQL modules

1.0.5 (2026-03-05)

  • Add Data Model module (CloudBaseDataModel)
    • CRUD operations with filter, select, orderBy, expand support
    • Batch create/update/delete operations
    • Upsert support
    • Raw MySQL command execution
    • DataSource query APIs (aggregate list, detail, schema, table name)
  • Refactor HTTP client with token auto-refresh and improved documentation
  • Add example code for Data Model
  • Add unit tests for Data Model

1.0.4 (2026-01-16)

  • Add example code

1.0.3 (2026-01-16)

  • Update README documentation

1.0.2 (2026-01-15)

  • Fix HTTP client not handling empty token string correctly

1.0.1 (2026-01-15)

  • Improve README documentation with complete authentication API usage

1.0.0 (2026-01-15)

  • Initial release
  • Authentication module (CloudBaseAuth)
    • Email/phone registration and sign-in
    • Password sign-in
    • OTP verification sign-in
    • OAuth third-party sign-in
    • IdToken sign-in
    • Custom ticket sign-in
    • Anonymous sign-in
    • Session management (get, refresh, set)
    • User information management
    • Identity provider binding/unbinding
    • Password reset
  • Cloud Functions module (CloudBaseFunctions)
    • Basic cloud function invocation
    • Function-based cloud run invocation
  • Cloud Run module (CloudBaseCloudRun)
    • HTTP methods support (GET/POST/PUT/DELETE)
    • Custom request headers
  • API Gateway module (CloudBaseApis)
    • Chained calls
    • Multiple HTTP methods support
  • Captcha module (CloudBaseCaptcha)
    • Image captcha
    • Custom captcha handler
    • Built-in captcha dialog