appsonair_flutter_push_notification 0.0.2-alpha
appsonair_flutter_push_notification: ^0.0.2-alpha copied to clipboard
Flutter plugin for the AppsOnAir Push Notification service (Android/iOS).
AppsOnAir-Flutter-PushNotification #
A Flutter plugin wrapping the native AppsOnAir Push Notification SDKs (Android/iOS) โ device registration, rich notifications, taps/actions, tags, aliases, opt-in/opt-out, and more, behind one Dart API.
Warning
Alpha release โ not for production use.
0.0.2-alpha is an early preview, intended for evaluation, prototypes, and internal test
builds. Do not ship it in a production app or one with a large user base.
- The public API may change without notice and may not stay source-compatible โ expect to update your integration between releases.
- Breaking changes are not limited to major versions while the SDK is pre-1.0.
- Not yet proven at scale; some behaviour is still unverified in real-world use.
Pin this exact version rather than a version range, and re-test on every upgrade.
Note
Deprecation notice.
This package will be deprecated and discontinued in favor of the new
appsonair_flutter_apppush package.
Migration guidance will be shared ahead of the transition.
Features Overview #
- Push Token ๐ฎ
Get notified whenever the FCM token (Android) or APNs device token (iOS) is issued or refreshed.
- Notification Received & Opened ๐ฌ
Listen for notifications as they arrive and when the user taps them, including any tapped action button.
- Foreground Display Control ๐ฅ๏ธ
Decide whether a notification received while the app is in the foreground is shown by the system, or suppressed so you can handle it yourself.
- Identity & Tags ๐ท๏ธ
Associate the device with a signed-in user (
login/logout), and segment your audience with key/value tags, aliases, and email addresses.
- Opt-in / Opt-out ๐
Pause or resume delivery to a device without touching OS-level notification permission.
- Consent (GDPR) โ
Gate all data collection on explicit user consent.
- Permission Handling ๐
Check and request the notification permission, including a fallback to the system Settings page when it has been permanently denied.
- Notification Management ๐๏ธ
Clear all delivered notifications, remove a single one by ID, or (Android) remove a group.
- Debug Logging ๐
Configure the SDK's logging verbosity for local development.
To learn more about AppsOnAir Push, please visit the AppsOnAir website
Android Setup #
Minimum Requirements #
- Android: API 24 (7.0) or higher
- Kotlin: Version 2.2.20 or higher
- Gradle: Version 8.0 or higher
- Firebase:
google-services.json(the SDK uses Firebase Cloud Messaging)
Add meta-data to the app's AndroidManifest.xml file under the application tag.
Make sure meta-data name is โAppsonairAppIdโ.
Provide your application id in meta-data value.
<application>
...
<meta-data
android:name="AppsonairAppId"
android:value="********-****-****-****-************" />
</application>
Add the notification icon/color used by Firebase Cloud Messaging (optional, but recommended so notifications don't fall back to your launcher icon):
<application>
...
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/notification_accent" />
</application>
Add below code to settings.gradle.kts (needed to resolve the native Push SDK, and its own
dependency AppsOnAir Core, from JitPack):
pluginManagement {
โฆโฆ
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven("https://jitpack.io")
}
}
Add below code to your root level build.gradle.kts:
allprojects {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
Apply the Google Services plugin (required by Firebase Cloud Messaging), in your root
build.gradle.kts:
plugins {
id("com.google.gms.google-services") version "4.4.2" apply false
}
and your app-level build.gradle.kts:
plugins {
id("com.google.gms.google-services")
}
iOS Setup #
Minimum Requirements #
iOS deployment target: 15.0
Provide your application id in your app Info.plist file.
<key>AppsonairAppId</key>
<string>XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX</string>
If CFBundleDisplayName is not added in your app then add it in your app Info.plist file.
<key>CFBundleDisplayName</key>
<string>YourAppName</string>
In Xcode, enable the Push Notifications capability (Target โ Signing & Capabilities โ + Capability โ Push Notifications) and, if you want background delivery of data-only pushes, Background Modes โ Background fetch.
APNs tokens are not available on the iOS Simulator โ test push registration on a real device.
iOS Dependency Manager #
This plugin supports both CocoaPods and Swift Package Manager (SPM). SPM support requires Flutter 3.24.0 or higher.
By default, CocoaPods is used. You can control which dependency manager your project uses by
adding the following to your app's pubspec.yaml:
Option 1 โ CocoaPods (default)
No extra steps needed. Run:
flutter pub get
cd ios && pod install
Option 2 โ Swift Package Manager
Requires Flutter โฅ 3.24.0.
Enable SPM globally via the Flutter CLI (one-time setup):
flutter config --enable-swift-package-manager
Then run:
flutter pub get
Flutter will automatically resolve AppsOnAir-AppPush via SPM from GitHub. No Podfile or
additional Xcode configuration required.
To switch back to CocoaPods:
flutter config --no-enable-swift-package-manager
Summary
| Flutter SPM config | Flutter version | Result |
|---|---|---|
| disabled (default) | any | CocoaPods |
| enabled | โฅ 3.24.0 | Swift Package Manager |
๐ก Recommendation: We recommend migrating to Swift Package Manager โ it is Apple's official, actively maintained dependency manager and receives updates first.
Example #
Initialize the SDK once, as early as possible. Call runApp before initialize to avoid
a white screen if the channel is not ready yet:
import 'package:appsonair_flutter_push_notification/appsonair_flutter_push_notification.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
await AppPushService.initialize();
}
Alternatively, initialize inside your root widget's initState:
@override
void initState() {
super.initState();
AppPushService.initialize();
}
initialize() reads the app ID from the AppsonairAppId manifest meta-data (Android) /
Info.plist entry (iOS) declared above โ no need to pass it from Dart.
Listening for events #
AppPushService.addTokenListener((token, apnsEnvironment) {
// Android: FCM token, apnsEnvironment is always null.
// iOS: hex APNs token, apnsEnvironment is "sandbox" or "production".
print('Token: $token');
});
AppPushService.addNotificationReceivedListener((notification) {
print('Received: ${notification.title}');
});
AppPushService.addNotificationOpenedListener((notification) {
print('Opened: ${notification.title}');
});
AppPushService.addErrorListener((error) {
print('[${error.code}] ${error.message}');
});
Requesting notification permission #
final granted = await AppPushService.isPermissionGranted();
if (!granted) {
await AppPushService.Notifications.requestPermission();
}
// Permanently denied? Send the user to Settings instead:
await AppPushService.Notifications.requestPermission(fallbackToSettings: true);
Controlling foreground display #
AppPushService.Notifications.addForegroundWillDisplayListener((event) {
// Do nothing โ the SDK shows it.
// Call preventDefault() โ suppressed entirely, handle it yourself.
event.preventDefault();
});
Handling taps and action buttons #
AppPushService.Notifications.addClickListener((event) {
final actionId = event.actionId; // null = body tap, else the tapped action's ID
print('Tapped ${event.notification.title}, action: $actionId');
});
Identity, tags, aliases, and email #
await AppPushService.login('user_12345');
await AppPushService.logout();
await AppPushService.User.addTagWithKey('plan', 'premium');
await AppPushService.User.addTags({'plan': 'premium', 'region': 'us'});
await AppPushService.User.removeTag('plan');
final tags = await AppPushService.User.getTags();
await AppPushService.User.addAlias('crm_id', 'CRM-9876');
await AppPushService.User.addEmail('user@example.com');
await AppPushService.User.setLanguage('fr');
Opt-in / opt-out #
await AppPushService.User.pushSubscription.optOut();
await AppPushService.User.pushSubscription.optIn();
final optedIn = await AppPushService.User.pushSubscription.isOptedIn;
Consent (GDPR) #
await AppPushService.setConsentRequired(true);
await AppPushService.initialize();
await AppPushService.setConsentGiven(true); // user accepted
await AppPushService.setConsentGiven(false); // user withdrew
Managing delivered notifications #
await AppPushService.clearAllNotifications();
await AppPushService.Notifications.removeNotification('order-4821');
await AppPushService.Notifications.removeGroupedNotifications('orders'); // Android only
Debug logging #
await AppPushService.Debug.setLogLevel(LogLevel.verbose);
await AppPushService.initialize();