Initialization
Initialize the Abrova Sync SDK with your API key from the Abrova Console, then open the realtime sync channel on Flutter, React Native, Web, Android, iOS, Node.js, or via REST API.
Once installed, the SDK needs two things to come alive: your Project API Key (read from the Abrova Console) and, on Flutter, React Native, Android and iOS, a connect() call that opens the realtime channel (the Web SDK connects on its own). Only the language and entry-point shape differ.
Two things you need
API Key
From Console → Your Org → Project. Safe to embed in mobile / web apps.
Server Secret
Only for server-side (Node.js / REST). Never embed in a client.
Flutter#
import 'package:abrova_sync/abrova_sync.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize AbrovaSync with your API key
await AbrovaSync.init(AbrovaSyncConfig(
apiKey: 'YOUR_API_KEY', // Get from Abrova Console
));
// Connect to start realtime sync
await AbrovaSync.connect();
runApp(MyApp());
}React Native#
import AbrovaSync from '@abrova/sync-react-native';
// Initialize in your app entry point
async function initializeApp() {
await AbrovaSync.init({
apiKey: 'YOUR_API_KEY', // Get from Abrova Console
});
// Connect to start realtime sync
await AbrovaSync.connect();
}
initializeApp();Web#
import AbrovaSync from '@abrova/sync-web';
// Initialize AbrovaSync with your API key
const abrovaSync = new AbrovaSync({
apiKey: 'YOUR_API_KEY', // Get from Abrova Console (Project API Key)
});
// The web SDK connects to realtime on its own - there is no connect() call.Android#
import ir.abrova.sync.sdk.AbrovaSync
import ir.abrova.sync.sdk.AbrovaSyncConfig
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize AbrovaSync with your API key
val config = AbrovaSyncConfig.Builder("YOUR_API_KEY") // Get from Abrova Console
.debugMode(true) // Optional: enable debug logging
.build()
// Create AbrovaSync instance
val abrovaSync = AbrovaSync.initialize(this, config)
}
}
// Connect when ready (in Activity/Fragment)
lifecycleScope.launch {
AbrovaSync.getInstance().connect()
}iOS#
import AbrovaSync
// Initialize in AppDelegate or App struct
@main
struct MyApp: App {
init() {
let config = AbrovaSyncConfigBuilder(
apiKey: "YOUR_API_KEY" // Get from Abrova Console
)
.debugMode(true) // Optional: enable debug logging
.build()
AbrovaSync.initialize(config: config)
}
var body: some Scene {
WindowGroup {
ContentView()
.task {
try? await AbrovaSync.shared.connect()
}
}
}
}Node.js#
The Node.js SDK uses service account auth — both apiKey and serverSecret are required. Use it from a backend, never from a client: the server secret can mint a token for any user in your project.
import { AbrovaSyncAdmin } from '@abrova/sync-node';
const abrovaSync = new AbrovaSyncAdmin({
apiKey: process.env.ABROVA_API_KEY!, // Your Project API Key
serverSecret: process.env.ABROVA_SERVER_SECRET!, // Required for server-side operations
});
// Mint a user token for your app. This is the only way auth.uid in Security
// Rules becomes something the server can trust.
const { token, expiresIn } = await abrovaSync.createUserToken(session.userId);Once a database has rules, they are evaluated for the Node.js SDK exactly as they are for a client, with auth.uid set to the userId you pass in its config — see Security Rules. The one difference: a database with no rules saved is locked to client SDKs, but not to a request carrying your server secret.
REST API#
The REST API has no init step — every request just carries the auth headers. Get your credentials from Console → Your Org → Projects → API Key + Server Secret, then attach them to any HTTP client:
# Example: list the documents in a collection (database and collection by name) curl -X GET "https://sync.abrova.ir/databases/my-app/collections/todos/documents/sdk" \ -H "x-api-key: YOUR_PROJECT_API_KEY" \ -H "x-server-secret: YOUR_SERVER_SECRET" \ -H "Content-Type: application/json"
Telling Abrova who the user is#
Security Rules read auth.uid. Your app cannot set it: the API key it ships with is public, so the server has no reason to believe a user id that comes from a client. Instead, your backend mints a short-lived user token with your server secret, and the SDK sends it on every request.
Give the SDK a token provider and it handles the rest — fetching a token when it needs one and refreshing it shortly before expiry. The provider returns null when no one is signed in. It is the same Abrova user token Abrova Chat and Abrova Push use, so one function can serve every SDK. (Flutter and React Native have the provider from 0.2.1; on any client SDK you can instead fetch the token yourself and pass it with setUserToken() / userTokens.set().)
// Web
const abrovaSync = new AbrovaSync({
apiKey: 'YOUR_API_KEY',
tokenProvider: async () => {
// Your own endpoint, behind your own session check.
const res = await fetch('/api/abrova-sync-token', { method: 'POST' });
return (await res.json()).token;
},
});// Flutter await AbrovaSync.init(AbrovaSyncConfig( apiKey: 'YOUR_API_KEY', tokenProvider: () => myBackend.fetchAbrovaToken(), // null when signed out ));
// React Native
await AbrovaSync.init({
apiKey: 'YOUR_API_KEY',
tokenProvider: () => myBackend.fetchAbrovaToken(), // null when signed out
});// Android
val config = AbrovaSyncConfig.builder("YOUR_API_KEY")
.userTokenProvider { myBackend.fetchAbrovaSyncToken() } // called off the main thread
.build()// iOS
let sync = AbrovaSync.initialize(config: config)
sync.userTokens.provider = { try await myBackend.fetchAbrovaSyncToken() }When the user signs in or out
Tell the SDK, and it asks the provider again and reconnects as that user:
| SDK | Call |
|---|---|
| Flutter, React Native | AbrovaSync.refreshUserToken() |
| Web | abrovaSync.refreshUserToken() |
| Android | sync.userTokens.refresh() |
| iOS | sync.refreshUserToken() |
If you pass tokens yourself instead of using a provider, call setUserToken(token) (Flutter, React Native, Web) or userTokens.set(token) (Android, iOS) with the new user's token, or with null / nil on sign-out.
Connecting before anyone is signed in
Without a token the SDK falls back to an unverified user id, which a project with Require signed user tokens turned on will refuse. From 0.2.1 that is not an error on any client SDK: call connect() at app start as usual (the Web SDK connects on its own). The SDK waits, and connects by itself as soon as it has a token. To know it is waiting, use onAwaitingUserToken or isAwaitingUserToken.
// Flutter
AbrovaSync.onAwaitingUserToken(() => print('Sync connects after sign-in'));
await AbrovaSync.connect(); // completes normally
// ... later, after your own sign-in:
await AbrovaSync.refreshUserToken(); // the SDK connects nowSee Security Rules.
Next: CRUD operations.