Flutter Notification Permission on Android 13+: POST_NOTIFICATIONS, When to Ask and Handling Deny (2026)
Do Flutter apps need to ask for notification permission on Android 13+?
Yes. Since Android 13 (API level 33), posting non-exempt notifications needs the POST_NOTIFICATIONS runtime permission, and on a fresh install of Android 13 or higher, notifications are off by default until the user allows them. If your Flutter app shows reminders, chat alerts or FCM messages and you never request the permission, those notifications simply don't appear for new users, with no crash and no error in your logs. This is how I handle it in my own apps: declare the permission, ask at a moment that makes sense, handle "Don't allow" gracefully, and test the denied path before release.
What Android actually does
Android's documentation on the notification runtime permission sets out the rules that matter for a Flutter app:
- Target 13 or higher: your app decides when to show the permission dialog. Nothing happens until you ask.
- Target 12L or lower: the system shows the dialog itself the first time your app starts an activity after creating a notification channel. If the user taps "Don't allow", the app can't ask again until it's reinstalled or updated to target 13+.
- Existing installs upgraded to 13: if the app already had a notification channel and notifications weren't turned off, the system pre-grants the permission. New installs get no such help.
- Swiping the dialog away doesn't change the permission state; it stays undecided.
Because Play requires recent target API levels anyway (see my notes on the target API 36 deadline), every maintained app is in the first group: you have to ask.
Step 1: declare the permission
Add this to android/app/src/main/AndroidManifest.xml, outside the <application> tag:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
Some plugins merge it in for you, but I declare it explicitly so the manifest shows what the app asks for. Without the declaration, the request is never shown.
Step 2: request it from Dart
Pick the plugin you already use, rather than adding another:
- permission_handler:
await Permission.notification.request()returns a status you can check (granted, denied, permanently denied). - flutter_local_notifications: resolve the Android implementation with
resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()and callrequestNotificationsPermission(). - firebase_messaging: Firebase's Flutter docs say that on Android 13 or newer you must ask the user's permission before FCM payloads can be received on the device, using
FirebaseMessaging.instance.requestPermission().
Whichever you use, call it once at the right time and store nothing that assumes the answer; read the current status on every app start, because the user can change it in system settings.
Step 3: ask at the right moment
Android's guidance is to ask in context, when the user can see why the app needs notifications, rather than at first launch. In practice I ask right after the user turns on something that depends on notifications: a reminder, an alert for a price, or a reply notification. A one-line explanation in your own UI before the system dialog helps people understand what they're agreeing to. The same "ask after a positive moment" thinking applies to rating prompts, which I covered in in-app review prompt timing.
Step 4: handle "Don't allow"
If the user declines, the app keeps working; it just can't post notifications. Make that visible where it matters, for example a small banner on the reminders screen with a button that opens the app's notification settings. Don't keep re-requesting: since Android 11, if the user denies a permission more than once the system stops showing the dialog, and permission_handler reports the permission as permanently denied, so the only route is settings.
Two exceptions are worth knowing. Media session notifications are exempt from the permission, and so are self-managed calling apps that use CallStyle. Foreground services don't need the permission to start, but they still need a notification; if the permission is denied, the user sees the foreground service notice in the Task Manager rather than the notification drawer.
Step 5: test the denied path
Use a test device on Android 13 or newer and run through four cases: fresh install and allow, fresh install and deny, deny then enable in settings, and an upgrade from an older build. Android's documentation lists ADB commands to simulate a new install between runs: adb shell pm revoke <package> android.permission.POST_NOTIFICATIONS, followed by pm clear-permission-flags for the user-set and user-fixed flags. For push, also confirm token handling still works when the user enables notifications later; my FCM token hygiene routine covers that. If you schedule reminders, pair this with the exact alarms policy notes, because a reminder that fires without notification permission is invisible.
A short release checklist
- Permission declared in the manifest.
- Request tied to a feature the user just enabled, with a one-line explanation.
- Status checked on every launch, not cached.
- Clear "notifications are off" state with a link to settings.
- Denied path tested on a fresh install, Android 13+.
Where to put the request in a Flutter app
In practice I keep all notification permission logic in one small service class: a method that returns the current status, a method that requests it, and a method that opens settings. Screens never call the plugin directly. That way, the onboarding flow, the reminder toggle and the settings page all show the same state, and when a plugin changes its API after an update I only fix one file. I also log the result of the request (granted or denied, never anything personal) to my analytics, which tells me whether the explanation screen is working. If the grant rate is low, the wording or the timing usually needs to change, not the code.
One more detail: Android notification channels still matter after the permission is granted. Users can turn off individual channels, so give each type of notification its own clearly named channel. Someone who wants reminders but not promotions can then keep the permission on instead of disabling everything.
FAQ
Why don't my Flutter notifications show on Android 13 with no error?
New installs have notifications off by default. Without the POST_NOTIFICATIONS grant, the system silently doesn't display them.
Do I need POST_NOTIFICATIONS for FCM?
Yes, for notifications the user sees. Firebase's Flutter documentation says to request permission on Android 13 or newer before FCM payloads can be received on the device.
Can I ask again after the user taps "Don't allow"?
You can, but after repeated denials Android stops showing the dialog. Send the user to the app's notification settings instead.
Does a foreground service need the notification permission?
No, it can start without it, but it still needs a notification. If the permission is denied, the notice appears in the Task Manager instead of the drawer.
Which Flutter plugin should I use to request it?
Use the one already in your app. permission_handler, flutter_local_notifications and firebase_messaging can all show the Android dialog, so there's no need to add a second plugin just for this.
Sources
- Android Developers: Notification runtime permission (checked 2026-10-30)
- Firebase: Receive messages in a Flutter app (requesting permission) (checked 2026-10-30)
- pub.dev: permission_handler (checked 2026-10-30)
- pub.dev: flutter_local_notifications (checked 2026-10-30)