Flutter SDK Setup
Instructions for adding the OneSignal Flutter SDK to your Flutter app for iOS and Android
Step 1. Requirements
- OneSignal Account
- OneSignal App ID, available in Settings > Keys & IDs
iOS Requirements
- iOS 11+ or iPadOS 11+ device (iPhone, iPad, iPod Touch) to test on. Xcode 14+ simulator works running iOS 16+
- mac with Xcode 12+
- p8 Authentication Token or p12 Push Notification Certificate
Android Requirements
- Android 4.1+ device or emulator with "Google Play Store (Services)" installed
- Set up your Google/Firebase keys in OneSignal
- Project using AndroidX.
- Project with
compileSdkVersion
of 33 or higher (Higher than the default for Flutter 2.8.0+).
Amazon & Huawei Requirements
Follow these instructions if your app is distributed on the Amazon AppStore and/or the Huawei AppGallery.
Step 2. Add the OneSignal Flutter SDK
2.1 To add the OneSignal Flutter SDK to your project, edit your project's pubspec.yaml
file:
dependencies:
onesignal_flutter: ^3.5.0
2.2 Run flutter pub get
to install the SDK. Or, if you are using Android Studio, Click Pub get
in the action ribbon at the top of pubspec.yaml.
2.3 Now, in your Dart code, you can use:
import 'package:onesignal_flutter/onesignal_flutter.dart';
Step 3. Add an iOS Service Extension (iOS Apps Only)
The OneSignalNotificationServiceExtension allows your application (in iOS) to receive rich notifications with images and buttons, along with Badges and Confirmed Deliveries.
3.1 Within your project's ios folder, open the .xcworkspace
file in Xcode.
3.2 Select File
> New
> Target
3.3 Select Notification Service Extension
and press Next
3.4 Enter the Product Name as OneSignalNotificationServiceExtension
and Language to Objective-C (if you need to use Swift that is ok).
Then click Finish. Do not select "Activate" on the dialog shown after selecting "Finish".
3.5 Press Cancel
on the Activate Scheme
prompt
By canceling, you are keeping Xcode set to debug your app instead of the extension. If you selected Activate by accident, you can simply switch back to debug your app in Xcode (next to the Play button).
3.6 In the Project Navigator, select the top-level project directory and select the OneSignalNotificationServiceExtension
target.
Ensure the Deployment Target
is set to the same value as your Main Application Target. Unless you have a specific reason not to, you should set the Deployment Target
to be iOS 10 which is the version of iOS that Apple released Rich Media for push. iOS versions under 10 will not be able to get Rich Media.
3.7 Close the Xcode project. In the /ios
directory of your project, open the Podfile
and add the following outside of the main target (should be at the same level as your main target):
target 'OneSignalNotificationServiceExtension' do
use_frameworks!
pod 'OneSignalXCFramework', '>= 3.4.3', '< 4.0'
end
# Uncomment this line to define a global platform for your project
platform :ios, '9.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
target 'OneSignalNotificationServiceExtension' do
use_frameworks!
pod 'OneSignalXCFramework', '>= 3.4.3', '< 4.0'
end
3.8 At the top of your Podfile
make sure you have platform :ios, '9.0'
.
- Or a newer iOS version if your app requires it.
# Uncomment this line to define a global platform for your project
platform :ios, '9.0'
3.9 Open terminal, cd
to the ios
directory, and run pod install
.
If you see the error below, remove #
from the above in front of use_frameworks!
and try again.
- Runner (true) and OneSignalNotificationServiceExtension (false) do not both set use_frameworks!.
3.10 Reopen the .xcworkspace
file in Xcode.
Make sure to always open the workspace file.
In your project, in the OneSignalNotificationServiceExtension/
folder, open NotificationService.m
and replace the whole file contents with:
#import <OneSignal/OneSignal.h>
#import "NotificationService.h"
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNNotificationRequest *receivedRequest;
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.receivedRequest = request;
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
//If your SDK version is < 3.5.0 uncomment and use this code:
/*
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest
withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
*/
/* DEBUGGING: Uncomment the 2 lines below and comment out the one above to ensure this extension is excuting
Note, this extension only runs when mutable-content is set
Setting an attachment or action buttons automatically adds this */
// NSLog(@"Running NotificationServiceExtension");
// self.bestAttemptContent.body = [@"[Modified] " stringByAppendingString:self.bestAttemptContent.body];
// Uncomment this line to set the default log level of NSE to VERBOSE so we get all logs from NSE logic
//[OneSignal setLogLevel:ONE_S_LL_VERBOSE visualLevel:ONE_S_LL_NONE];
[OneSignal didReceiveNotificationExtensionRequest:self.receivedRequest
withMutableNotificationContent:self.bestAttemptContent
withContentHandler:self.contentHandler];
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
[OneSignal serviceExtensionTimeWillExpireRequest:self.receivedRequest withMutableNotificationContent:self.bestAttemptContent];
self.contentHandler(self.bestAttemptContent);
}
@end
import UserNotifications
import OneSignal
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var receivedRequest: UNNotificationRequest!
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.receivedRequest = request
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
//If your SDK version is < 3.5.0 uncomment and use this code:
/*
OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: self.bestAttemptContent)
contentHandler(bestAttemptContent)
*/
/* DEBUGGING: Uncomment the 2 lines below to check this extension is excuting
Note, this extension only runs when mutable-content is set
Setting an attachment or action buttons automatically adds this */
//OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE)
//bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
contentHandler(bestAttemptContent)
}
}
}
Ignore Any Build Errors
The build errors will disappear once you run the app.
3.11 Finally, you will need to enable an App Group to use Confirmed Deliveries and increment/decrement Badges through push notifications.
Please follow the iOS SDK App Groups setup guide to add the OneSignal App Group in your app.
Step 4. Enable iOS Push Capability in Xcode (iOS Apps Only)
4.1 In the main app target, select Signing & Capabilities > All > + Capability, enable Push Notifications.
4.2 Next, enable Background Modes and check Remote Notifications.
Step 5. Set up OneSignal for Android
Verify the Android compileSdkVersion
is at least 33
for your project. Open your android/app/build.gradle
file and inspect the compileSdkVersion
property.
-
If
compileSdkVersion
in yourandroid/app/build.gradle
file is set toflutter.compileSdkVersion
, open yourandroid/local.properties
file and ensure a property offlutter.compileSdkVersion
is either non-existent or is set to a value of33
or higher. -
If
compileSdkVersion
in yourandroid/app/build.gradle
file is set to a number less than 33, update it to a value of33
or higher:
// ...
android {
compileSdkVersion 33
// ...
}
// ...
For more information about the Gradle build configuration in relation to Flutter, view the Flutter documentation
Step 6. Initialize the OneSignal SDK (All Platforms)
6.1 You can now initialize OneSignal using the following code in your main.dart
file:
//Remove this method to stop OneSignal Debugging
OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);
OneSignal.shared.setAppId("YOUR_ONESIGNAL_APP_ID");
// The promptForPushNotificationsWithUserResponse function will show the iOS or Android push notification prompt. We recommend removing the following code and instead using an In-App Message to prompt for notification permission
OneSignal.shared.promptUserForPushNotificationPermission().then((accepted) {
print("Accepted permission: $accepted");
});
6.2 You can also add observers for various events, such as a new notification being received or opened, or observe changes to the subscription status:
OneSignal.shared.setNotificationWillShowInForegroundHandler((OSNotificationReceivedEvent event) {
// Will be called whenever a notification is received in foreground
// Display Notification, pass null param for not displaying the notification
event.complete(event.notification);
});
OneSignal.shared.setNotificationOpenedHandler((OSNotificationOpenedResult result) {
// Will be called whenever a notification is opened/button pressed.
});
OneSignal.shared.setPermissionObserver((OSPermissionStateChanges changes) {
// Will be called whenever the permission changes
// (ie. user taps Allow on the permission prompt in iOS)
});
OneSignal.shared.setSubscriptionObserver((OSSubscriptionStateChanges changes) {
// Will be called whenever the subscription changes
// (ie. user gets registered with OneSignal and gets a user ID)
});
OneSignal.shared.setEmailSubscriptionObserver((OSEmailSubscriptionStateChanges emailChanges) {
// Will be called whenever then user's email subscription changes
// (ie. OneSignal.setEmail(email) is called and the user gets registered
});
Step 7. Run Your App and Send Yourself a Notification
Run your app on a physical device to make sure it builds correctly. Note that the iOS Simulator does not support receiving remote push notifications.
- Android devices should be subscribed to push notifications immediately upon opening the app.
- iOS devices should be prompted to subscribe to push notifications if you used the example setup code provided.
Check your OneSignal Dashboard Audience > All Users to see your Device Record.
Then head over to Messages > New Push to Send your first Push Notification from OneSignal.
Troubleshooting
If you run into any issues please see our Flutter troubleshooting guide.
Try the example project on our Github repository.
If stuck, contact support directly or email [email protected] for help.
For faster assistance, please provide:
- Your OneSignal App Id
- Details, logs, and/or screenshots of the issue.
- Steps to reproduce
Step 8. Set Custom User Properties
Recommended
After initialization, OneSignal will automatically collect common user data by default. Use the following methods to set your own custom userIds, emails, phone numbers, and other user-level properties.
Set External User Id
Required if using integrations.
Recommended for messaging across multiple channels (push, email, sms).
OneSignal creates channel-level device records under a unique Id called the player_id
. A single user can have multiple player_id
records based on how many devices, email addresses, and phone numbers they use to interact with your app.
If your app has its own login system to track users, call setExternalUserId
at any time to link all channels to a single user. For more details, see External User Ids.
let externalUserId = '123456789'; // You will supply the external user id to the OneSignal SDK
OneSignal.shared.setExternalUserId(externalUserId);
Set Email and Phone Number
Recommended if using Email and SMS messaging.
Use the provided SDK methods to capture email and phone number when provided. Follow the channel quickstart guides for setup:
// Pass in email provided by customer
OneSignal.shared.setEmail("[email protected]");
// Pass in phone number provided by customer
OneSignal.shared.setSMSNumber(smsNumber: "+11234567890")
Data Tags
Optional
All other event and user properties can be set using Data Tags. Setting this data is required for more complex segmentation and message personalization.
await OneSignal.shared.sendTag("test", "value");
Step 9. Implement a Soft-Prompt In-App Message
Optional
It is recommended that apps create an alert, modal view, or other interface that describes the types of information they want to send and gives people a clear way to opt in or out.
OneSignal provides an easy option for a "soft-prompt" using In-App Messages to meet this recommendation and have a better user experience. This also permits you to ask for permission again in the future, since the native permission prompt can no longer be shown in your app if the user clicks deny.
See our How to Prompt for Push Permissions with an In-App Message Guide for details on implementing this.
Setup Complete!
Visit Mobile Push Tutorials for next steps.
Updated over 1 year ago