The Android 13 notification permission, POST_NOTIFICATIONS
Notifications are off by default on Android 13 and later. How to declare and ask for POST_NOTIFICATIONS in context, handle two denials, and test it with adb.
Since Android 13 (API level 33), showing a notification needs a runtime permission, POST_NOTIFICATIONS, like the camera or location. New installs start with notifications off. If your FCM sends return success and nothing appears on newer phones, this is the first thing to check.
What changes, by target SDK
| Your app targets | On an Android 13+ phone |
|---|---|
| API 33 or higher | You decide when to ask. Until the user allows, nothing shows |
| API 32 or lower | The system asks by itself the first time an activity starts after you create a notification channel, usually at launch. One “Don’t allow” and it never asks again until a reinstall or an update that targets 33 |
| Any, updated from before the phone moved to 13 | The permission is granted automatically if the app had a channel and the user had not turned notifications off |
Google Play requires new apps and updates to target a recent API level, so in practice you are in the first row and the asking is your job.
1. Declare it
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
2. Ask in context
Ask when the user does something that makes notifications obviously useful: turns on order updates, follows someone, books something. A prompt on first launch, before the user knows the app, gets denied more often, and two denials end the conversation.
class OrderActivity : ComponentActivity() {
private val askNotifications = registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
if (!granted) showSettingsHint()
}
private fun onTrackOrderTapped() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return
when {
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED -> Unit
shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS) -> showWhyDialog { askNotifications.launch(Manifest.permission.POST_NOTIFICATIONS) }
else -> askNotifications.launch(Manifest.permission.POST_NOTIFICATIONS)
}
}
}
shouldShowRequestPermissionRationale returns true after one denial. That is the moment to explain in a sentence what the user will get, then ask once more.
In Compose, the same contract works through rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()). In React Native call PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS); in Expo, Notifications.requestPermissionsAsync(); in Flutter with firebase_messaging, FirebaseMessaging.instance.requestPermission(). The rule about asking in context is the same.
3. After a second “Don’t allow”
The dialog will not appear again. Send the user to the app’s notification settings instead:
fun openNotificationSettings(context: Context) {
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
context.startActivity(intent)
}
4. Know who can see notifications
Data messages still arrive with the permission denied, so a valid FCM token does not mean a visible notification. Check before you send something that must be seen, and tell your server:
val canShow = NotificationManagerCompat.from(context).areNotificationsEnabled()
A user can also allow notifications but switch off one channel. NotificationManagerCompat.getNotificationChannelCompat(id)?.importance == IMPORTANCE_NONE tells you that.
What is exempt
- Notifications from media sessions (playback controls).
- Apps that manage their own phone calls, for
CallStylenotifications. - Foreground services can start without the permission; their notification then shows in the Task Manager, not the notification drawer.
Test each case with adb
# a fresh install on Android 13+
adb shell pm revoke com.example.app android.permission.POST_NOTIFICATIONS
adb shell pm clear-permission-flags com.example.app android.permission.POST_NOTIFICATIONS user-set
adb shell pm clear-permission-flags com.example.app android.permission.POST_NOTIFICATIONS user-fixed
# the user allowed it
adb shell pm grant com.example.app android.permission.POST_NOTIFICATIONS
Still missing after the permission?
The permission is one of several reasons. A missing channel, a data-only message to a killed app, Doze, and the battery savers on Xiaomi, Oppo and Vivo are the others: FCM says success but the notification never arrives and push on Xiaomi, Oppo, Vivo and Realme. SignOps Push sends to the tokens you register and removes the ones Google calls dead; the Android setup guide covers the permission step in the app.
Sources: Android Developers: Notification runtime permission, Android Developers: Request runtime permissions.