Notifications (Flutter)
The Flutter layer should treat Bubbl notifications as data payloads and render modal UI in Dart.
Event sources
notificationEvents() emits payloads from:
- Live in-app events while app is open
- Notification-open payload handoff from native layer
Subscribe in Flutter
import 'dart:async';
import 'package:bubbl_flutter_sdk/bubbl_flutter_sdk.dart';
final BubblFlutterSdk sdk = BubblFlutterSdk.instance;
late final StreamSubscription<Map<String, dynamic>> notificationSub;
notificationSub = sdk.notificationEvents().listen((payload) {
// Normalize + render your custom modal UI.
print('bubbl notification => $payload');
});
Typical payload shape
{
"id": 123,
"headline": "Title",
"body": "Body",
"mediaUrl": "https://...",
"mediaType": "image|video|audio",
"ctaLabel": "Open",
"ctaUrl": "https://...",
"locationId": "456",
"postMessage": "Thanks",
"questions": [...],
"raw": "{...original json...}"
}
Keep raw for compatibility/debug when upstream payload schema evolves.
Track lifecycle and CTA events
await sdk.trackSurveyEvent(
notificationId: '123',
locationId: '456',
activity: 'notification_delivered',
);
await sdk.trackSurveyEvent(
notificationId: '123',
locationId: '456',
activity: 'dismissed',
);
await sdk.cta(notificationId: 123, locationId: '456');
await sdk.trackSurveyEvent(
notificationId: '123',
locationId: '456',
activity: 'cta_engagement',
);
Submit survey responses
await sdk.submitSurveyResponse(
notificationId: '123',
locationId: '456',
answers: const <BubblSurveyAnswer>[
BubblSurveyAnswer(
questionId: 1,
type: 'RATING',
value: '5',
),
BubblSurveyAnswer(
questionId: 2,
type: 'MULTIPLE_CHOICE',
value: 'YES',
choice: <BubblChoiceSelection>[
BubblChoiceSelection(choiceId: 10),
BubblChoiceSelection(choiceId: 12),
],
),
],
);
Local test notification helper
final bool ok = await sdk.testNotification();
print('test notification => $ok');
Use this to validate event wiring and modal flow without backend push dependencies.