Amba

Flutter SDK

Flutter quickstart for the amba Dart package — pubspec dep, Amba.configure(), first track, first collection insert, platform-channel notes for sign-in and push.

Amba for Flutter is published to pub.dev as amba. One package, every platform Flutter supports.

Supported platforms: iOS 13+, Android API 24+, macOS 12+, Windows 10+, Linux (x86_64).

1. Add the dependency

flutter pub add amba

Or in pubspec.yaml:

dependencies:
  amba: ^1.0.0
  flutter:
    sdk: flutter

Run flutter pub get. The pub publisher attaches the prebuilt native binaries per platform, so no separate build step is needed.

2. Configure at app start

// lib/main.dart
import 'package:flutter/material.dart';
import 'package:amba/amba.dart';
 
Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Amba.configure(
    apiKey: const String.fromEnvironment('AMBA_API_KEY', defaultValue: 'amb_dev_ck_XXXX'),
  );
  runApp(const MyApp());
}

Pass the key via --dart-define:

flutter run --dart-define=AMBA_API_KEY=amb_dev_ck_XXXX
flutter build apk --dart-define=AMBA_API_KEY=amb_live_ck_XXXX

Amba.configure() is idempotent only for the first call — the underlying amba_init rejects re-init with "amba already initialized". To swap tenants in the same process, use the SDK's reset flow (amba_reset via the FFI) before re-calling configure. For typical apps this never matters: configure once at boot.

3. First sign-in (anonymous)

events.track is authenticated server-side — the request needs a session token. Mint one anonymously on first launch:

import 'package:amba/amba.dart';
 
final session = await Amba.auth.signInAnonymously();
debugPrint('signed in as ${session['user']['id']}');

signInAnonymously() returns a Map<String, dynamic>; cast through your own model classes for type safety. The session token persists across app restarts (amba writes to platform-appropriate storage), so you only mint a new anonymous session on first launch.

4. First event

Once a session exists, track engagement events:

await Amba.events.track('app_opened', {'source': 'icon'});

5. Sign in with Apple

Use sign_in_with_apple on iOS, then forward the identity token:

import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:amba/amba.dart';
 
Future<void> signInWithApple() async {
  final credential = await SignInWithApple.getAppleIDCredential(
    scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName],
  );
  if (credential.identityToken != null) {
    await Amba.auth.signInWithApple(credential.identityToken!);
  }
}

Enable the Sign in with Apple capability in Xcode (ios/Runner/Runner.entitlements) before building.

6. Sign in with Google

Use google_sign_in for the OAuth dance, then forward the idToken:

import 'package:google_sign_in/google_sign_in.dart';
import 'package:amba/amba.dart';
 
final _googleSignIn = GoogleSignIn(
  serverClientId: 'YOUR_GOOGLE_OAUTH_WEB_CLIENT_ID',
);
 
Future<void> signInWithGoogle() async {
  final account = await _googleSignIn.signIn();
  if (account == null) return;
  final auth = await account.authentication;
  if (auth.idToken != null) {
    await Amba.auth.signInWithGoogle(auth.idToken!);
  }
}

The serverClientId is the Web OAuth client ID from Google's API credentials console — not iOS or Android. Set up iOS in ios/Runner/Info.plist (CFBundleURLTypes) and Android in android/app/build.gradle per the google_sign_in setup guide.

7. Register for push

Use firebase_messaging on both platforms — it handles APNs registration on iOS and FCM on Android, returning a single token type per platform that you forward to amba:

import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:amba/amba.dart';
 
Future<void> registerForPush() async {
  final messaging = FirebaseMessaging.instance;
  final settings = await messaging.requestPermission();
  if (settings.authorizationStatus != AuthorizationStatus.authorized) return;
 
  final token = Platform.isIOS
      ? await messaging.getAPNSToken()
      : await messaging.getToken();
  if (token == null) return;
 
  await Amba.push.register(
    token,
    Platform.isIOS ? 'apns' : 'fcm',
    bundleId: 'com.example.myapp',
  );
}

Add the Push Notifications capability + Background Modes → Remote notifications in Xcode for iOS. For Android, add Firebase the standard way (google-services.json in android/app/).

8. First collection insert

import 'package:amba/amba.dart';
 
final inserted = await Amba.collections.insert(
  'posts',
  {'title': 'Hello amba', 'body': 'first post from Flutter'},
);
 
final response = await Amba.collections.find('posts', {
  'order': [{'column': 'created_at', 'direction': 'desc'}],
  'limit': 20,
});
debugPrint('got ${(response['data'] as List).length} posts');

For typed reads, cast through your own model classes or generate them with json_serializable.

9. AI proxy

final response = await Amba.ai.anthropic.messages.create({
  'prompt_slug': 'support_assistant',
  'variables': {'user_query': 'How do I cancel?'},
  'max_tokens': 1024,
});
debugPrint(response.toString());

Constructor DI for tests

// test/my_test.dart
import 'package:amba/amba.dart';
import 'package:flutter_test/flutter_test.dart';
 
class FakeBindings implements AmbaBindings {
  // implement the abstract methods with in-memory fakes
}
 
void main() {
  test('client sends correct payload', () async {
    final client = AmbaClient(bindings: FakeBindings());
    await client.initialize(apiKey: 'test');
    await client.events.track('test_event');
    // assert on the fake's recorded calls
  });
}

AmbaClient accepts an AmbaBindings via the constructor — tests inject a fake, production code goes through the singleton Amba.configure(...) which wires real native bindings.

Platform notes

PlatformNative libraryNotes
iOSstatic lib linked into the appStatically linked — no .framework to embed. Sign in / push via platform packages above.
Androidlibamba_core.so in jniLibs/<abi>/Same four ABIs as the Kotlin SDK (arm64-v8a, armeabi-v7a, x86_64, x86).
macOSlibamba_core.dylib in app bundleCode-signed; entitlements unchanged from default Flutter macOS apps.
Windowsamba_core.dll next to the .exeRequires MSVC runtime; ships in the standard Flutter Windows installer.
Linuxlibamba_core.so next to the binaryx86_64 only; tested on Ubuntu 22.04 + Fedora 39.
Webnot supported (Flutter for Web)Use @layers/amba-web from JS interop if you must.

Common pitfalls

  • Amba.configure not called before any other Amba.* access throws StateError("Amba.configure must be called before accessing Amba.*"). Always configure in main() after WidgetsFlutterBinding.ensureInitialized().
  • Hot-reload re-running main() — calling Amba.configure() again throws AmbaException("amba already initialized") on the second run. Wrap with a try/catch for development:
    try {
      await Amba.configure(apiKey: ...);
    } on AmbaException catch (e) {
      if (!e.message.contains('already initialized')) rethrow;
    }
  • Native library not found at runtime — verify it shipped in the build output. For Android: unzip -l build/app/outputs/flutter-apk/app-release.apk | grep amba_core. For iOS: otool -L Runner.app/Runner | grep amba_core.
  • Apple sign-in works in simulator, fails on device — the entitlement requires the app to be signed with a provisioning profile that includes the Sign in with Apple capability. Re-fetch the profile in Xcode after enabling.

See also

On this page