Why push notifications go missing on Xiaomi, Oppo, Vivo and Realme
Battery savers on Xiaomi, Redmi, Poco, Oppo, Realme, Vivo and OnePlus stop apps and drop pushes. What developers can change in the app and what users must switch on.
The same push arrives instantly on a Pixel and never on a Redmi. FCM is not the problem. Xiaomi, Redmi, Poco, Oppo, Realme, Vivo, iQOO and OnePlus add their own battery management on top of Android. It stops apps the user is not looking at, and a stopped app gets no pushes. These brands sell most of the phones in India, so for an Indian app this is the biggest single cause of missing notifications.
What these phones do
- Autostart off by default. On MIUI and HyperOS (Xiaomi, Redmi, Poco) and on ColorOS (Oppo, Realme), many apps are not allowed to start themselves. A push that needs your app’s code to run cannot.
- Swipe away acts like force stop. Clearing an app from recents can put it in the same state as Settings, Force stop. Android does not deliver messages to a force-stopped app until the user opens it.
- Battery saver profiles. Background activity is restricted per app, sometimes after a few days of the app not being opened.
- Lock screen and floating notifications off. The notification arrives but only shows in the shade, and the user thinks it never came.
What you can change in your app
- Send notification messages for anything the user must see. The system tray shows them without your code running, which survives more of these restrictions than data-only messages. See FCM notification not received.
- Use high priority for messages the user is waiting for, like a login approval or an order update, and normal for the rest.
- Separate channels. Logins and offers on different channels, so muting one does not mute the other.
- Ask once, at the right moment. When a user turns on something that depends on pushes, show one screen explaining the setting and a button that opens it. Do not show it to everyone on day one.
- Pull as well as push. When the app opens, fetch anything the user should have been told. Pushes that never arrived are then only late, not lost.
Opening the right settings screen
Android gives you a standard screen for battery optimization. The maker-specific Autostart screens have no public API, so link to the app’s settings page and tell the user which switch to turn on.
// The system list where the user can exempt your app from battery optimization
startActivity(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
// Your app's own settings page, where Autostart and battery options live on most phones
startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
Uri.fromParts("package", packageName, null)))
Google Play allows apps to ask for a direct exemption (REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) only in a few cases, so most apps should use the settings screen.
What to tell users, brand by brand
| Phone | Settings to change |
|---|---|
| Xiaomi, Redmi, Poco (MIUI, HyperOS) | Turn on Autostart for the app. Battery saver: No restrictions. Notifications: allow on lock screen and floating. Lock the app in recents. |
| Oppo, Realme (ColorOS, Realme UI) | Battery: Allow background activity and Allow auto launch. Notifications: allow all. |
| Vivo, iQOO (Funtouch OS, OriginOS) | Battery: allow High background power consumption. Turn on Autostart in i Manager or Settings. |
| OnePlus (OxygenOS) | Battery optimization: Don’t optimize for the app. Turn off Deep optimization if the phone has it. |
Menu names move between versions. dontkillmyapp.com keeps current instructions for each brand.
How to tell if this is your problem
Send the same notification to a Pixel or Samsung and to the Xiaomi, both with the app swiped away. If it shows on the first and not the second, it is the battery saver, and no server change will fix it alone.
How SignOps handles it
SignOps Push sends notification messages with high priority only where the user expects them, and the delivery log shows which devices accepted each push. For Approve, the SDK fetches pending approvals every time your app opens, so an approval held back by a battery saver still reaches the user, and your server can fall back to an email code if nobody answers.
Sources: Don’t kill my app, Android: optimize for Doze and App Standby, Firebase: receive messages in an Android app.