> For the complete documentation index, see [llms.txt](https://dnotifier.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dnotifier.gitbook.io/product-docs/platform-guides/flutter.md).

# Flutter (Android, iOS, Web)

The DNotifier **Dart SDK** is a pure Dart package that runs on **Flutter** for Android, iOS, Web, and desktop targets. No platform channels or native plugins are required in the SDK — WebSocket and HTTP are handled by `web_socket_channel` and `http`.

## Requirements

| Requirement           | Version                                             |
| --------------------- | --------------------------------------------------- |
| Flutter               | 3.x recommended                                     |
| Dart SDK              | 3.0 or later                                        |
| DNotifier credentials | From [app.dnotifier.com](https://app.dnotifier.com) |

→ [Install — Dart / Flutter](/product-docs/getting-started/installation/dart-flutter.md)

***

## Add the dependency

In `pubspec.yaml`:

```yaml
dependencies:
  flutter:
    sdk: flutter
  dnotifier: ^1.1.10
```

```bash
flutter pub get
```

Check [pub.dev/packages/dnotifier](https://pub.dev/packages/dnotifier) for the latest version.

***

## Platform support

| Target                  | WebSocket (`ws`) | HTTP (`http`) | Notes                                                      |
| ----------------------- | ---------------- | ------------- | ---------------------------------------------------------- |
| Android                 | ✅                | ✅             | No extra native config                                     |
| iOS                     | ✅                | ✅             | App Transport Security allows `api.dnotifier.com` over TLS |
| Web                     | ✅                | ✅             | Uses browser WebSocket via package                         |
| Windows / macOS / Linux | ✅                | ✅             | Where Flutter desktop is supported                         |

{% hint style="info" %}
The same Dart code runs on every Flutter target. Platform differences (permissions, background execution) are handled by your app, not the SDK.
{% endhint %}

***

## Connect in a Flutter widget

```dart
import 'package:flutter/material.dart';
import 'package:dnotifier/dnotifier.dart';

class ChatConnection extends StatefulWidget {
  const ChatConnection({super.key, required this.userId});
  final String userId;

  @override
  State<ChatConnection> createState() => _ChatConnectionState();
}

class _ChatConnectionState extends State<ChatConnection> {
  late final DNotifier _notifier;
  String _status = 'Connecting…';

  @override
  void initState() {
    super.initState();
    _notifier = DNotifier(
      appId: const String.fromEnvironment('DNOTIFIER_APP_ID'),
      secret: const String.fromEnvironment('DNOTIFIER_SECRET'),
      transport: 'ws',
      userId: widget.userId,
      onConnected: () => setState(() => _status = 'Connected'),
      onMessage: _handleMessage,
      onDisconnected: ({code, reason}) {
        setState(() => _status = 'Disconnected');
      },
    );
    _notifier.connect().catchError((e) {
      setState(() => _status = 'Error: $e');
    });
  }

  void _handleMessage(DNotifierMessage msg) {
    final body = msg.payload.toJSON();
    debugPrint('From ${msg.metadata.sender}: $body');
  }

  @override
  void dispose() {
    _notifier.disconnect();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Text(_status);
  }
}
```

Run with compile-time defines:

```bash
flutter run \
  --dart-define=DNOTIFIER_APP_ID=your-app-id \
  --dart-define=DNOTIFIER_SECRET=your-secret
```

→ [Credentials & environment](/product-docs/getting-started/credentials.md)

***

## State management

Wrap the `DNotifier` instance in your preferred pattern:

| Pattern                 | Approach                                                |
| ----------------------- | ------------------------------------------------------- |
| **Provider / Riverpod** | Register a singleton service; expose connection state   |
| **Bloc / Cubit**        | Emit events from `onMessage`; call `send` from handlers |
| **GetX**                | `Get.put(DNotifierService())` with lifecycle hooks      |

Keep one connection per authenticated user session. Call `disconnect()` when the user logs out.

***

## Sending messages

```dart
_notifier.send(
  senderId: widget.userId,
  receiverId: otherUserId,
  data: {'type': 'text', 'text': 'Hello from Flutter'},
  saveHistory: true,
);
```

Multiple receivers:

```dart
_notifier.send(
  senderId: widget.userId,
  receiverIds: ['user-b', 'user-c'],
  data: {'type': 'text', 'text': 'Hello everyone'},
);
```

→ [Your first message — Dart / Flutter](/product-docs/getting-started/first-message/dart-flutter.md)

***

## AI and workflows on mobile

Use `transport: 'http'` for `sendAI`, knowledge-base APIs, and `runWorkflow`. Common pattern:

* **Chat UI** — `ws` for realtime messages
* **AI screen or backend** — `http` for prompts and RAG

You can hold two `DNotifier` instances with different transports, or route AI through your own API.

→ [Choose your transport](/product-docs/getting-started/choose-transport.md)

***

## Background and lifecycle

{% hint style="warning" %}
Mobile OSes suspend apps in the background. WebSocket connections may close when the app is backgrounded.
{% endhint %}

| Event                       | Recommended action                      |
| --------------------------- | --------------------------------------- |
| `AppLifecycleState.paused`  | Optionally disconnect to save battery   |
| `AppLifecycleState.resumed` | Reconnect with backoff if disconnected  |
| User logout                 | `disconnect()` and dispose the instance |

```dart
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  if (state == AppLifecycleState.resumed && !_notifier.isConnected) {
    _notifier.connect();
  }
}
```

***

## Flutter Web specifics

* WebSocket uses the browser's native socket — same behavior as the [browser JavaScript guide](/product-docs/platform-guides/browser.md)
* Do not embed production secrets in compiled web assets; use `--dart-define` only for dev or proxy through your backend
* Test reconnection when the user switches browser tabs

***

## Permissions

The SDK does not require microphone, camera, or notification permissions. Add those in your app only if you build voice, video, or push features on top of DNotifier messaging.

***

## Workflows and agents

```dart
final agent = DNotifier.defineAgent(
  name: 'intent-agent',
  run: (ctx) async {
    await ctx.sendAI(
      message: {'text': 'Classify intent'},
      saveHistory: false,
      label: 'Intent',
    );
    return {'intent': 'search'};
  },
);

final workflow = DNotifier.Workflow(
  name: 'intent-router',
  observability: true,
  entry: (ctx) async {
    final result = await ctx.runAgent('intent-agent');
    return result;
  },
).registerAgents({'intent-agent': agent});
```

Use `transport: 'http'` and `await notifier.runWorkflow(...)`.

→ [Workflows overview](/product-docs/workflows-and-agents/overview.md)

***

## Troubleshooting

| Issue                          | Fix                                                    |
| ------------------------------ | ------------------------------------------------------ |
| `Authentication failed`        | Verify app ID and secret                               |
| `StateError: Not connected`    | Await `connect()` before `send()`                      |
| Works on Android, fails on iOS | Check network / ATS; ensure TLS to `api.dnotifier.com` |
| Web build secret exposed       | Move auth to backend                                   |

→ [Troubleshooting](/product-docs/operations/troubleshooting.md)

***

## Next steps

* [Your first connection — Dart / Flutter](/product-docs/getting-started/first-connection/dart-flutter.md)
* [Pure Dart platform guide](/product-docs/platform-guides/pure-dart.md)
* [Example: Minimal chat app](/product-docs/chat/example-minimal-chat/dart-flutter.md)
