The Ditto Flutter SDK is an edge sync platform allowing devices to synchronize data with or without an internet connection.

For more info, go to docs.ditto.live

Platforms

Platform Supported
iOS Yes
Android Yes
Web Coming Soon
MacOS Planned
Windows Planned
Linux Planned

Prerequisites

Installation

  • Run the following command in your terminal from the root of your application.
flutter pub add ditto_live

Warning

The first build on Android requires a pre-processing step that can take up to 10 minutes. Subsequent builds will be able to skip this step

Mobile App Permissions

Set the following platform specific permissions to allow your application to access device level capabilities. This will enable Ditto to use BLE, LAN, and P2P Wi-Fi to establish peer-to-peer connections and sync data without an internet connection.

  • (iOS Development) Add the following permissions to ios/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Uses Bluetooth to connect and sync with nearby devices</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Uses Bluetooth to connect and sync with nearby devices</string>
<key>NSLocalNetworkUsageDescription</key>
<string>Uses WiFi to connect and sync with nearby devices</string>
<key>NSBonjourServices</key>
  • (Android Development) Add the following permissions to android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.BLUETOOTH"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
    android:usesPermissionFlags="neverForLocation"
    tools:targetApi="s" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
    android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
    android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
    android:usesPermissionFlags="neverForLocation"
    tools:targetApi="tiramisu" />

Usage

Initialization

First, create an instance of Ditto. This is the main entrypoint into all Ditto-related functionality.


final identity = await OnlinePlaygroundIdentity.create(
    appId: "YOUR_APP_ID", // Replace with your specific id
    token: "YOUR_PLAYGROUND_TOKEN", // Replace with your specific token
);
final ditto = await Ditto.open(identity);

await ditto.startSync();

Executing a local data store query

To execute a query, use ditto.store.execute(...).

final results = await ditto.store.execute("SELECT * FROM users");

for (final result in results) {
    print("I got ${result.value}");
}

You can also use execute to insert or modify data:

final result = await ditto.store.execute(
    "INSERT INTO users DOCUMENTS (:user1)",
    arguments: {
        "user1": {
            "name": "John",
            "age": 123,
        },
    },
);

expect(result.mutatedDocumentIDs, hasLength(1));

For more information on writing queries review the Ditto Query Language section in the Ditto docs.

Observe local data store changes

You can use a StoreObserver to listen to changes to your local database:

final observer = await ditto.store.registerObserver(
    "SELECT * FROM users",
    onChange: (queryResult) => print("we got some changes"),
);

StoreObserver also exposes a Stream for easier use in Flutter:

final observer = await ditto.store.registerObserver("SELECT * FROM users");

return StreamBuilder(
    stream: observer.stream,
    builder: (context, snapshot) {
        final items = snapshot.data!.items;
        return Text("We have ${items.length} items");
    },
);

Syncing Data

In order to synchronize data with other devices, you need to create a SyncSubscription:

final subscription = await ditto.sync.registerSubscription("SELECT * FROM users");

// when you're done, cancel the subscription
await subscription.cancel();

For more information, go to docs.ditto.live

Libraries

ditto_live
The Flutter SDK for Ditto