PocketBase Dart SDK

repository·master·Indexed 20 days ago

https://github.com/pocketbase/dart-sdk

The official multi-platform client for interacting with the PocketBase Web API in Dart and Flutter applications. It provides tools for authentication, real-time subscriptions, file uploads, and CRUD operations via RecordService. Key features include BatchService for atomic requests, AsyncAuthStore for persistent authentication, and a CollectionService for administrative schema management.

Tokens
11.9K
Snippets
46
Records
55
Agent score
72%

What's inside pocketbase-dart-sdk

  1. Manage authentication with AuthStore

    master

    The pb.authStore service manages the authenticated token and user record.

    Key features:

    • Logout: Call pb.authStore.clear() to clear the current session.
    • Listening: Listen to the onChange stream to react to auth changes.
    • Persistence: The default AuthStore is not persistent. To persist auth state across app restarts, use AsyncAuthStore with a storage layer like shared_preferences or hive.

    Example: Persistent Auth with shared_preferences

    final prefs = await SharedPreferences.getInstance();
    
    final store = AsyncAuthStore(
     save:    (String data) async => prefs.setString('pb_auth', data),
     initial: prefs.getString('pb_auth'),
    );
    
    final pb = PocketBase('http://example.com', authStore: store);
    final store = AsyncAuthStore(
     save:    (String data) async => prefs.setString('pb_auth', data),
     initial: prefs.getString('pb_auth'),
    );
    
    final pb = PocketBase('http://example.com', authStore: store);
  2. Initialize and use the PocketBase client

    master

    Import the package and initialize the PocketBase client with your server URL. You can then perform authentication, list records with filters, and subscribe to real-time changes.

    import 'package:pocketbase/pocketbase.dart';
    
    // Initialize the client
    final pb = PocketBase('http://127.0.0.1:8090');
    
    // Authenticate as a regular user
    final userData = await pb.collection('users').authWithPassword('test@example.com', '123456');
    
    // List and filter records
    final result = await pb.collection('example').getList(
      page:    1,
      perPage: 20,
      filter:  'status = true && created >= "2022-08-01"',
      sort:    '-created',
      expand:  'someRelField',
    );
    
    // Subscribe to real-time changes
    pb.collection('example').subscribe("*", (e) {
      print(e.action); // create, update, delete
      print(e.record); // the changed record
    }, filter: "someField > 10");
    import 'package:pocketbase/pocketbase.dart';
    
    final pb = PocketBase('http://127.0.0.1:8090');
    
    // authenticate as regular user
    final userData = await pb.collection('users').authWithPassword('test@example.com', '123456');
    
    // list and filter "example" collection records
    final result = await pb.collection('example').getList(
      page:    1,
      perPage: 20,
      filter:  'status = true && created >= "2022-08-01"',
      sort:    '-created',
      expand:  'someRelField',
    );
    
    // subscribe to realtime "example" collection changes
    pb.collection('example').subscribe("*", (e) {
      print(e.action); // create, update, delete
      print(e.record); // the changed record
    }, filter: "someField > 10");
  3. Install the PocketBase Dart SDK

    master

    To use the PocketBase Dart SDK, add it to your project's dependencies using the following commands:

    For Dart projects:

    dart pub add pocketbase

    For Flutter projects:

    flutter pub add pocketbase
    dart pub add pocketbase
    # or with Flutter:
    flutter pub add pocketbase
  4. Development tasks for the PocketBase Dart SDK

    master

    If you are contributing to or developing with the SDK source, use the following commands:

    • Run unit tests: dart test
    • View documentation locally: dart doc
    • Run the provided example: dart run example/example.dart
    • Generate DTOs: Use build_runner to generate json_serializable artifacts for Data Transfer Objects (DTOs).
    # run the unit tests
    dart test
    
    # view dartdoc locally
    dart doc
    
    # run the example
    dart run example/example.dart
    
    # generate the DTOs json serializable artifacts
    dart run build_runner build
  5. How batch/transactional operations work

    master

    Batch operations allow you to group multiple record requests (create, update, delete, upsert) into a single atomic transaction.

    To use batching, you should not initialize BatchService manually. Instead, use PocketBase.createBatch(). This returns a BatchService instance which provides access to SubBatchService instances for specific collections via the .collection(collectionIdOrName) method.

    Once you have queued your desired operations using the SubBatchService methods, call .send() on the main BatchService to execute the transaction. The result is returned as a List<BatchResult> representing the outcome of each individual request in the batch.

    // Example of batching operations
    final batch = pb.createBatch();
    
    // Queue a create operation
    batch.collection('posts').create(body: {"title": "Hello World"});
    
    // Queue an update operation
    batch.collection('posts').update('RECORD_ID', body: {"title": "Updated Title"});
    
    // Execute the batch
    final results = await batch.send();
  6. Optimize performance with reuseHTTPClient

    master

    By default, the SDK creates a new http.Client for every request. For high-frequency requests, you can enable persistent connections by setting reuseHTTPClient: true in the PocketBase constructor.

    Warning: If you enable this, you must call pb.close() when the SDK instance is no longer needed (e.g., during app termination) to properly close the connections.

    final pb = PocketBase('http://127.0.0.1:8090', reuseHTTPClient: true);
    
    // ... later
    pb.close();
  7. How the PocketBase client manages authentication and requests

    master

    The PocketBase client automatically manages authentication and request headers:

    1. Authentication: If the authStore contains a valid token, the client automatically adds the Authorization header to every request unless it is manually overridden.
    2. Language: The lang property is sent as the Accept-Language header in every request.
    3. Error Handling: All response errors (including HTTP 4xx/5xx and network failures) are normalized and wrapped in a ClientException. This exception includes the url, statusCode, and the originalError (or the JSON response body if available).
    4. Multipart Requests: When providing files in a request, the client automatically switches to a MultipartRequest and encodes the body into a @jsonPayload field.
  8. Handle real-time connection and disconnection

    master

    You can monitor the lifecycle of the real-time connection using the following methods:

    • onDisconnect hook: An optional callback void Function(Map<String, List<SubscriptionFunc>>)? that is invoked when the client disconnects. This happens if you unsubscribe from all topics or if the connection is interrupted/closed by the server. It receives the map of current subscriptions as an argument, which can help you determine if the disconnect was intentional.
    • PB_CONNECT event: To detect when a connection is established or re-established, subscribe to the special PB_CONNECT topic.
    • clientId: A getter that returns the established SSE connection client ID.
    // Listen for connection events
    pb.realtime.subscribe("PB_CONNECT", (e) {
      print("Connected with ID: ${pb.realtime.clientId}");
    });
    
    // Handle unexpected disconnections
    pb.realtime.onDisconnect = (subscriptions) {
      print("Disconnected. Active subscriptions before disconnect: ${subscriptions.keys.toList()}");
    };
  9. Initialize the PocketBase client

    master

    To interact with your PocketBase backend, create an instance of the PocketBase class. You must provide the baseURL (e.g., 'http://127.0.0.1:8090').

    Configuration Options

    • lang: Optional language code for the Accept-Language header (defaults to en-US).
    • authStore: An optional instance of AuthStore. If not provided, a new one is created.
    • reuseHTTPClient: If set to true, the client initializes a single persistent HTTP client for all requests to improve performance. Note: If you enable this, you must call pb.close() when finished to clean up resources.
    • httpClientFactory: An optional factory to provide a custom http.Client implementation.
    final pb = PocketBase('http://127.0.0.1:8090', reuseHTTPClient: true);
    
    // ... use the client ...
    
    // Always close if reuseHTTPClient was true
    pb.close();
  10. Limitations of the PocketBase Dart SDK

    master

    The PocketBase Dart SDK is built on top of the standard dart-lang/http package. As a result, it inherits the following limitation:

    • Request cancellation/abort is not supported: You cannot currently cancel or abort ongoing HTTP requests.