initDatabase function

void initDatabase({
  1. required String appId,
  2. required String apiKey,
  3. required String projectId,
  4. String? databaseUrl,
  5. String? storageBucket,
})

Creates the App. Idempotent.

The Database itself is created on first use, so databaseUrl is optional: a project with no Realtime Database has no firebase_url to give, and an app binding only Auth or Firestore never needs one.

Throws StateError rather than returning a code: a failure here is a configuration problem the caller cannot proceed past.

Implementation

void initDatabase({
  required String appId,
  required String apiKey,
  required String projectId,
  String? databaseUrl,
  String? storageBucket,
}) {
  if (!hasFirebase) {
    throw StateError(
      'this build has no Firebase SDK — configure with FDB_WITH_FIREBASE=ON '
      'and an SDK on CMAKE_PREFIX_PATH (or an emb augment)',
    );
  }
  final rc = fdbInitDartApi(NativeApi.initializeApiDLData);
  if (rc != 0) {
    throw StateError('Dart_InitializeApiDL failed: $rc');
  }

  final a = appId.toNativeUtf8();
  final k = apiKey.toNativeUtf8();
  final p = projectId.toNativeUtf8();
  // Empty rather than absent: the native side omits an empty url from the
  // options, and an app with none simply has no Database to reach.
  final u = (databaseUrl ?? '').toNativeUtf8();
  // Set on the app or not at all: Storage takes its bucket from the app's
  // options, and an app created without one fails the first operation with an
  // unknown error rather than refusing to initialize.
  final b = (storageBucket ?? '').toNativeUtf8();
  try {
    final result = fdbAppInit(a.cast(), k.cast(), p.cast(), u.cast(), b.cast());
    if (result != 0) {
      throw StateError('firebase App/Database init failed: $result');
    }
  } finally {
    for (final ptr in [a, k, p, u, b]) {
      calloc.free(ptr);
    }
  }
}