aquabase 0.7.1 copy "aquabase: ^0.7.1" to clipboard
aquabase: ^0.7.1 copied to clipboard

PlatformAndroid

Flutter SDK for Aquabase — encrypted real-time database with offline sync, tags, and binary transport.

example/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:aquabase/aquabase.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // ── Init ──────────────────────────────────────────────
  final app = await Aquabase.init(
    projectId: 'demo',
    apiKey: 'aq_pub_demo',
    // url: 'http://localhost:3280',       // optional
    // encrypted: true,                   // optional: encrypts ALL collections
    // localSync: LocalSync.enabled,       // optional: device-to-device LAN sync
  );

  // ── Auth ──────────────────────────────────────────────
  final session = await app.auth.register('user@test.com', 'pass123');
  debugPrint('Authenticated: ${session.uid}');
  debugPrint('Restored session: ${app.authSession?.uid}');
  // Existing user: await app.auth.login('user@test.com', 'pass123');
  // OAuth: app.auth.signInWithOAuth(context, OAuthProvider.google) drives the
  // whole flow in a bottom sheet over the in-app browser.

  // ── Collections ───────────────────────────────────────
  final users = app.collection('users'); // unencrypted, synced
  final students = app.collection(
    '_students',
    local: true,
  ); // local, unencrypted
  // ── Document CRUD ─────────────────────────────────────
  await users.doc('u1').set({
    'name': 'Ana',
    'age': 25,
    'createdAt': DateTime.now(),
  });
  // Reads return DocData: typed accessors that fall back when a field is
  // absent, null or written with another type. `createdAt` was written as a
  // DateTime and reads back as ms since epoch.
  final user = await users.doc('u1').get();
  debugPrint('User: ${user?.text('name')} (${user?.integer('createdAt')})');
  await users.doc('u1').delete(localOnly: true);

  final generatedId = await users.add({'name': 'Carlos', 'age': 30});
  final scopedId = await users.add({
    'name': 'Lucía',
    'age': 28,
  }, idPrefix: 'team_a_');
  debugPrint('Generated IDs: $generatedId, $scopedId');

  // ── Document write (auto-index) ──────────────────────
  final scores = app.collection('scores');
  await scores.doc('s1').set({
    'studentId': 'u1',
    'subject': 'math',
    'score': 95,
    'date': '2026-03-19',
  });

  // ── Equality query ────────────────────────────────────
  final mathScores = await scores
      .where('studentId', eq: 'u1')
      .where('subject', eq: 'math')
      .get();
  debugPrint('Math scores: ${mathScores.docs.length} results');

  // ── Range query ───────────────────────────────────────
  // score entre 90 y 100 (inclusivo)
  final highScores = await scores.where('score', from: 90, to: 100).get();
  debugPrint('High scores: ${highScores.docs.length} results');

  // fechas de marzo completo + filtro por studentId
  final marchScores = await scores
      .where('date', from: '2026-03-01', to: '2026-03-31')
      .where('studentId', eq: 'u1')
      .get();
  debugPrint('March scores: ${marchScores.docs.length} results');

  // ── isIn, count, exists and ordering ──────────────────
  final selectedScores = await scores
      .where('studentId', eq: 'u1')
      .where('subject', isIn: ['math', 'science'])
      .orderBy('score', descending: true)
      .get();
  final scoreCount = await scores.where('studentId', eq: 'u1').count();
  final hasHighScore = await scores
      .where('studentId', eq: 'u1')
      .where('subject', isIn: ['math', 'science'])
      .exists();
  debugPrint(
    'Selected: ${selectedScores.docs.length}, count: $scoreCount, exists: $hasHighScore',
  );

  // ── Cursor pagination ─────────────────────────────────
  final firstPage = await scores.where('studentId', eq: 'u1').fetchPage(20);
  if (firstPage.nextCursor != null) {
    final secondPage = await scores
        .where('studentId', eq: 'u1')
        .fetchPage(20, firstPage.nextCursor);
    debugPrint('Second page: ${secondPage.docs.length} results');
  }
  await for (final page in scores.where('studentId', eq: 'u1').paginate(20)) {
    debugPrint('Page: ${page.docs.length} results');
  }

  // ── Watch doc ─────────────────────────────────────────
  final sub1 = users.watch('u1').listen((data) {
    debugPrint('User changed: $data');
  });

  // ── Watch query ───────────────────────────────────────
  final sub2 = scores.where('subject', eq: 'math').watch().listen((results) {
    debugPrint('Math scores: ${results.docs.length}');
  });

  // ── Bulk ops ──────────────────────────────────────────
  await users.bulkSet({
    'u1': {'name': 'Ana'},
    'u2': {'name': 'Luis'},
    'u3': {'name': 'Carlos'},
  });
  final bulk = await users.bulkGet(['u1', 'u2', 'u3']);
  debugPrint('Bulk get: ${bulk.keys.length} docs');
  await users.bulkDelete(['u2', 'u3']);

  // ── Local collection ──────────────────────────────────
  await students.doc('s1').set({'name': 'Ana', 'age': 12, 'grade': '6A'});
  final student = await students.doc('s1').get();
  debugPrint('Student: $student');
  await students.bulkSet({
    's1': {'name': 'Ana'},
    's2': {'name': 'Luis'},
  });
  debugPrint('Local keys: ${students.localKeys()}');

  // ── Storage ───────────────────────────────────────────
  await app.storage.upload(
    'avatars',
    'photo.jpg',
    await File('photo.jpg').readAsBytes(),
    contentType: 'image/jpeg',
  );
  final photo = await app.storage.download('avatars', 'photo.jpg');
  debugPrint('Downloaded: ${photo.length} bytes');
  debugPrint('Public URL: ${app.storage.publicUrl('avatars', 'photo.jpg')}');
  await app.storage.refresh('avatars', 'photo.jpg');
  await app.storage.deleteFile('avatars', 'photo.jpg');

  // ── Logs ──────────────────────────────────────────────
  await app.logs.connect(); // also captures crashes
  app.logs.info('db', 'User created');
  app.logs.warn('auth', 'Failed login', source: '192.168.1.1');
  app.logs.error('ws', 'Timeout');
  final logs = await app.logs.query(
    LogQueryOptions(
      since:
          DateTime.now()
              .subtract(const Duration(hours: 1))
              .microsecondsSinceEpoch *
          1000,
      minLevel: LogLevel.warn,
      limit: 50,
    ),
  );
  debugPrint('Logs: ${logs.length} entries');

  // ── Offline status ────────────────────────────────────
  debugPrint('Connected: ${app.isConnected}');
  debugPrint('Pending ops: ${app.pendingOfflineOps}');
  await app.flushOfflineQueue();

  app.connectionState.listen((online) => debugPrint('Connection: $online'));
  app.deniedOperations.listen((id) => debugPrint('Denied: $id'));
  app.flushResults.listen((result) => debugPrint('Flush: $result'));
  app.backlogErrors.listen((event) {
    debugPrint(
      'Backlog: ${event.reason}, ${event.ops} ops, ${event.bytes} bytes',
    );
  });

  // ── Cleanup ───────────────────────────────────────────
  await sub1.cancel();
  await sub2.cancel();
  await app.clearAuth();
  await app.dispose();
}
0
likes
140
points
125
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter SDK for Aquabase — encrypted real-time database with offline sync, tags, and binary transport.

Homepage
Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

android_id, cryptography, cryptography_flutter, device_info_plus, flutter, google_sign_in, meta, msgpack_dart, package_info_plus, path_provider, url_launcher, web_socket_channel

More

Packages that depend on aquabase