offline_sync_flutter 1.0.2 copy "offline_sync_flutter: ^1.0.2" to clipboard
offline_sync_flutter: ^1.0.2 copied to clipboard

An automatic offline-first API synchronization system for Flutter apps. Handles request queue management, automatic sync when internet returns, and conflict resolution.

Offline Sync Flutter #

An advanced, production-ready offline-first API synchronization mechanism for Flutter applications.

Managing network requests in offline or poor-connectivity environments is traditionally complex, forcing developers to implement custom local databases, connectivity listeners, and background sync queues. offline_sync_flutter simplifies this entirely. By replacing your standard HTTP calls with the package's robust API, all requests are automatically queued locally when the device is offline, and transparently synced to the server the moment connectivity is restored.

Core Capabilities #

  • Persistent Offline Storage: Guarantees no data loss. Requests made offline are serialized and securely stored on the device until they can be successfully transmitted.
  • Intelligent Queue Management: Requests are maintained in a chronological queue. The engine processes them sequentially, ensuring data integrity and correct execution order on the backend.
  • Automatic Synchronization: Deeply integrated with platform connectivity streams. The sync engine wakes up and processes the local queue immediately when an active internet connection is detected.
  • Configurable Retry Policies: Network requests fail for various reasons. The built-in retry manager allows you to define maximum attempt limits and custom backoff delays for transient errors.
  • Multiple Storage Backends: Out-of-the-box support for both Hive (NoSQL, high-performance) and SQLite (relational, structured).
  • Conflict Resolution: Configurable strategies (serverWins, localWins, manual) to handle edge cases where remote data may have changed while the device was out of sync.
  • Reactive UI Components: Built-in Flutter widgets that reactively display synchronization states and pending queue counts to keep the user informed.

Installation #

Add the package to your pubspec.yaml file:

dependencies:
  offline_sync_flutter: ^1.0.0

Run flutter pub get to install the dependency.

Initialization #

Before making any requests, the synchronization engine must be initialized. The optimal place for this is within your main() method before calling runApp().

import 'package:flutter/material.dart';
import 'package:offline_sync_flutter/flutter_offline_sync.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  await OfflineSync.initialize(
    storage: HiveStorage(), // Defaults to Hive if omitted. Opt for SQLiteStorage() if you prefer SQL.
    retryAttempts: 3,
    retryDelay: const Duration(seconds: 5),
    conflictStrategy: ConflictStrategy.serverWins,
  );

  runApp(const MyApp());
}

Configuration Parameters #

  • storage: The persistent layer for your queued requests. You can pass HiveStorage(), SQLiteStorage(), or a custom implementation of the SyncStorage interface.
  • retryAttempts: The maximum number of times the engine will attempt to send a failed HTTP request before keeping it in the queue for a manual or later automated retry.
  • retryDelay: The duration the engine will wait between consecutive retry attempts.
  • conflictStrategy: Determines how HTTP headers are appended regarding conflict resolution. This exposes your intent to your backend API.

Making API Requests #

The package mirrors standard REST API methods. When you use the OfflineSync provider, the package automatically evaluates the network state. If the device is online, the request is dispatched normally. If offline, the payload, headers, and endpoint are serialized and stored.

// Submitting a standard POST request
try {
  await OfflineSync.post(
    url: "https://api.yourdomain.com/v1/records",
    headers: {
      "Authorization": "Bearer YOUR_TOKEN",
      "Content-Type": "application/json",
    },
    data: {
      "user_id": 1024,
      "payload": "Sample offline data",
      "timestamp": DateTime.now().toIso8601String(),
    },
  );
  print("Request processed successfully (or queued if offline).");
} catch (e) {
  print("An error occurred: $e");
}

The package supports .get(), .post(), .put(), .patch(), and .delete().

User Interface Integration #

Providing visual feedback during background synchronizations improves the user experience. offline_sync_flutter exposes reactive streams and pre-built widgets.

SyncIndicator #

A lightweight icon widget that updates its state based on the current engine status. It displays different icons and colors for offline, syncing (animated spinner), success, and failed states.

AppBar(
  title: const Text('Dashboard'),
  actions: const [
    Padding(
      padding: EdgeInsets.all(16.0),
      child: SyncIndicator(),
    ),
  ],
)

PendingRequestsBadge #

Wraps around any child widget (usually the SyncIndicator or a generic Cloud icon) to display a notification badge containing the exact number of requests currently waiting in the offline queue.

PendingRequestsBadge(
  child: Icon(Icons.cloud_upload),
)

SyncStatusBanner #

A drop-in banner widget designed for the top of a screen. It automatically hides itself when the queue is empty, but seamlessly animates into view to display the pending item count when the device goes offline and requests begin piling up.

Column(
  children: [
    const SyncStatusBanner(),
    Expanded(child: YourMainContent()),
  ],
)

Advanced Customization #

Custom Storage Layers #

If your application already uses a specific local database (such as Isar, ObjectBox, or Drift), you can easily map the sync mechanism to your existing architecture by extending the abstract SyncStorage class.

class MyCustomStorage implements SyncStorage {
  @override
  Future<void> initialize() async {
    // Setup your custom DB
  }

  @override
  Future<void> saveRequest(SyncRequest request) async {
    // Insert into DB
  }

  @override
  Future<List<SyncRequest>> getPendingRequests() async {
    // Return all pending requests, sorted by createdAt
  }

  @override
  Future<void> removeRequest(String id) async {
    // Delete from DB on success
  }

  @override
  Future<void> updateRequest(SyncRequest request) async {
    // Update retry counts
  }
}

Once implemented, pass it to the initialization method:

await OfflineSync.initialize(storage: MyCustomStorage());

System Architecture #

To understand the internal flow of the package:

  1. OfflineSync: The singleton facade managing the initialization and exposing the public API.
  2. SyncEngine: The orchestrator. It listens to connectivity changes and processes HTTP tasks sequentially.
  3. ConnectivityMonitor: A continuous listener hooked into the device's native network configurations.
  4. RequestQueue: The bridge between the synchronous engine and the asynchronous persistent storage.
  5. RetryManager: Decoupled logic strictly responsible for backoff intervals and failure counting.

Contributing #

We welcome contributions from the community. If you encounter bugs, have feature requests, or want to contribute code, please open an issue or submit a pull request on the repository.

  1. Fork the repository.
  2. Create your feature branch (git checkout -b feature/advanced-retry).
  3. Commit your changes.
  4. Push to the branch (git push origin feature/advanced-retry).
  5. Open a Pull Request.

License #

This project is licensed under the MIT License. See the LICENSE file for more details.

1
likes
140
points
9
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

An automatic offline-first API synchronization system for Flutter apps. Handles request queue management, automatic sync when internet returns, and conflict resolution.

Repository (GitHub)
View/report issues

Topics

#offline #sync #api #network #offline-first

License

MIT (license)

Dependencies

connectivity_plus, flutter, hive, hive_flutter, http, path, path_provider, sqflite

More

Packages that depend on offline_sync_flutter