-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Prerequisites
- I have searched for existing feature requests that might be similar
- I have read the documentation
- This feature would benefit the broader OSMEA community
Target Package
Core
Feature Type
New component/widget
Priority
High - Important for my use case
Problem Statement
Problem Statement: Missing OneSignal Helper
Currently, the project lacks a unified helper for OneSignal push notifications. Initialization, permission prompts, tagging/segmentation, and click-routing logic are implemented ad-hoc across different modules. This causes:
- Code Duplication: Repeating boilerplate for init, permissions, and handlers.
- Inconsistency: Divergent handling of notification payloads, deep links, and channels across features.
- Fragile Routing: Notification click → screen routing (deep links) handled differently per screen.
- Poor Observability: No single place to log outcomes/analytics or capture errors.
- Env Drift: App IDs and channel configs differ across dev/stage/prod without clear centralization.
- Maintainability Risks: Changes to SDK usage or OS permission rules require many scattered edits.
Proposed Solution
Proposed Solution: OneSignal Helper
Introduce a OneSignalHelper (e.g., lib/app/services/notifications/one_signal_helper.dart) that encapsulates all OneSignal concerns behind a clean, testable API.
Goals
- Single Entry Point for initialization, permissions, listeners, and routing.
- Flavor-Aware Config: Separate App IDs and defaults for dev/stage/prod.
- Consistent Payload Schema: Normalize additionalData to a typed model.
- Deterministic Routing: Centralize notification click →
AutoRoutenavigation. - Tagging/Segmentation Utilities: First-class methods for tags, aliases, externalId.
- Observability: Outcome events + error reporting hooks.
- Compliance: GDPR consent + Android/iOS permission nuances.
Suggested Interface (Dart Example)
class OneSignalConfig {
final String appId;
final bool allowProvisionalIOS; // iOS provisional auth
final bool autoPrompt; // defer if you need custom timing
final Map<String, String> defaultTags;
const OneSignalConfig({
required this.appId,
this.allowProvisionalIOS = true,
this.autoPrompt = false,
this.defaultTags = const {},
});
}
typedef NotificationRouteResolver = Future<void> Function(OneSignalPayload payload);
class OneSignalHelper {
static Future<void> init(OneSignalConfig config);
static Future<bool> requestPermission(); // Android 13+ & iOS
static Future<void> setExternalId(String userId);
static Future<void> setTags(Map<String, String> tags);
static Future<void> deleteTags(List<String> keys);
static Future<String?> getPlayerId(); // device/user id
static void onNotificationReceived(void Function(OneSignalPayload p) cb);
static void onNotificationOpened(NotificationRouteResolver resolver);
static void enableInAppMessages(bool enabled);
static Future<void> logOutcome(String name, {double? value});
}Routing Contract
- Normalize
additionalDatato aOneSignalPayloadwith fields like:target: route name (e.g.,"newsDetail")params:{ "id": "123", "category": "tech" }screenTracking: optional analytics key
The helper calls a provided NotificationRouteResolver to perform navigation:
context.router.push(NewsDetailRoute(id: payload.params['id']));Channels & Permissions
- Android: Create channels (high/low importance), badge count, sound/vibration defaults.
- iOS: Support provisional auth and explicit prompt; handle “Deliver Quietly” cases.
- GDPR/Consent: Expose
setConsentRequired,provideConsent.
Error & Retry
- Wrap SDK calls with safeguards (network issues) and exponential backoff where meaningful.
- Provide a simple internal logger hook so the app can forward to Crashlytics/Sentry.
Environment Management
- Read
ONE_SIGNAL_APP_IDper flavor from.env/--dart-defineand inject viaOneSignalConfig. - Enforce initialization before usage with an assert/guard.
Expected Benefits
- Consistency in permissions, tags, channels, and routing.
- Less Boilerplate, faster feature delivery.
- Better Analytics via centralized outcome logging.
- Safer Updates when SDK or OS rules change.
Alternatives Considered
No response
Use Cases
Use Cases: OneSignal Helper
1. First-Run Permission Flow
Defer the system notification prompt until after onboarding.
await OneSignalHelper.requestPermission();2. User-Scoped Targeting
After login, set the external user ID and tags for segmentation.
await OneSignalHelper.setExternalId(user.id);
await OneSignalHelper.setTags({"role": "seller"});3. Deep Link Routing
Open a specific screen (e.g., OrderDetail) when the user taps a notification.
OneSignalHelper.onNotificationOpened((payload) async {
if (payload.target == "orderDetail") {
context.router.push(OrderDetailRoute(id: payload.params["id"]));
}
});4. Segmented Campaigns
Apply tags to deliver targeted push notifications.
await OneSignalHelper.setTags({"lang": "tr", "tier": "gold"});5. In-App Messages for Announcements
Enable in-app messages for announcements or feature rollouts.
OneSignalHelper.enableInAppMessages(true);6. Outcome Tracking
Track outcomes when users interact with content from notifications.
await OneSignalHelper.logOutcome("open_news_detail");7. Compliance Mode (GDPR/Consent)
Ensure GDPR consent before activating OneSignal functionality.
OneSignal.setConsentRequired(true);
OneSignal.provideConsent(true);8. Multi-Flavor App IDs
Use different App IDs per environment (dev/stage/prod) to avoid mixing audiences.
9. Android 13+ Runtime Permissions
Prompt users for runtime notification permission with rationale.
10. Silent Update Hints
Handle silent push notifications to refresh cached content and show subtle in-app banners.
Mockups/Examples
No response
Implementation Ideas
No response
Contribution
- I would like to work on this feature
- I can help with testing
- I can help with documentation
- I can provide feedback during development
Additional Context
No response