How do push notifications work with Firebase Cloud Messaging in Flutter?
Short Answer
The app registers with FCM to get a unique device token, your backend (or Firebase console) sends a message to that token via the FCM API, and the `firebase_messaging` package delivers it to the app in foreground, background, or terminated states via different handlers.
Each app install gets a device token from `FirebaseMessaging.instance.getToken()`, which you send to your backend so it knows where to deliver messages for that user. When a message arrives, how it's handled depends on app state: in the foreground, `FirebaseMessaging.onMessage` fires and you typically show your own in-app notification UI (FCM doesn't auto-display foreground notifications). In the background or terminated, the OS shows the system notification automatically for "notification" payloads, and tapping it triggers `FirebaseMessaging.onMessageOpenedApp` (from background) or a check on `getInitialMessage()` (from terminated) so you can navigate to the right screen.
On iOS specifically, you also need to request notification permission explicitly (`requestPermission()`) and configure APNs certificates/keys in the Firebase console — FCM relies on Apple's push service under the hood for iOS delivery.
Common Mistakes
- ×Forgetting that foreground messages don't show a system notification automatically — you must build that UI yourself.
- ×Not registering a top-level (non-class) background message handler, which iOS/Android background isolates require.