A notification system that works perfectly in testing and silently fails for a third of users is one of the more demoralising bugs to chase. The usual cause is not your code. It is manufacturer-level battery management deciding your app should not run.
Several Android manufacturers layer their own aggressive power management on top of the platform's. Applications not on a whitelist get their background work suspended, their alarms delayed and, in some cases, their push messages held until the user next opens the app. The behaviour differs between manufacturers and between firmware versions of the same manufacturer.
Firebase Cloud Messaging priority is the first lever. High-priority messages are more likely to wake a dozing device; normal-priority messages may be batched until the next maintenance window. Marking everything high priority is not the answer either, since the platform penalises applications that do so without user-visible reason.
The reliable mitigation is asking the user. A one-time prompt guiding them to disable battery optimisation for your app works, and the platform provides an intent to open that settings screen directly. It feels awkward to ask, and it is far less awkward than a user who never receives an alert they were relying on.
Design for the failure rather than assuming it away. Anything genuinely important — a payment confirmation, an OTP, a delivery alert — needs a second channel or a state the user can pull when they open the app. A notification is a convenience, not a delivery guarantee, and on this platform that is literally true.
Test on the devices your users actually have. An emulator and a recent flagship will both behave correctly and tell you nothing. A cheap two-year-old handset from a popular Indian brand will tell you what your users are experiencing.