0
# Message Handling
1
2
Complete message lifecycle management for handling FCM messages in different app states: foreground, background, and when the app is launched from a notification.
3
4
## Capabilities
5
6
### Foreground Message Listener
7
8
Handles messages received while the app is active and in the foreground. These messages do not automatically display notifications.
9
10
```typescript { .api }
11
/**
12
* Called when any FCM payload is received while app is in foreground
13
* @param listener - Callback function receiving the RemoteMessage
14
* @returns Function to unsubscribe from message events
15
*/
16
function onMessage(listener: (message: RemoteMessage) => any): () => void;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import messaging from '@react-native-firebase/messaging';
23
24
// Listen for foreground messages
25
const unsubscribe = messaging().onMessage(async remoteMessage => {
26
console.log('FCM Message Data:', remoteMessage.data);
27
console.log('Notification payload:', remoteMessage.notification);
28
29
// Handle the message (show custom notification, update UI, etc.)
30
if (remoteMessage.notification) {
31
showCustomNotification(remoteMessage.notification);
32
}
33
});
34
35
// Unsubscribe when component unmounts
36
unsubscribe();
37
38
// Modular API
39
import { getMessaging, onMessage } from '@react-native-firebase/messaging';
40
const messagingInstance = getMessaging();
41
const unsubscribe = onMessage(messagingInstance, remoteMessage => {
42
console.log('Message received:', remoteMessage);
43
});
44
```
45
46
### Background Message Handler
47
48
Sets a global handler for messages received when the app is in the background or terminated. Must be called outside of React components.
49
50
```typescript { .api }
51
/**
52
* Set a message handler function called when app is in background or terminated
53
* @param handler - Async function to handle background messages
54
* @returns void
55
*/
56
function setBackgroundMessageHandler(handler: (message: RemoteMessage) => Promise<any>): void;
57
```
58
59
**Usage Examples:**
60
61
```typescript
62
// index.js or App.js (outside of React components)
63
import messaging from '@react-native-firebase/messaging';
64
65
messaging().setBackgroundMessageHandler(async remoteMessage => {
66
console.log('Message handled in the background!', remoteMessage);
67
68
// Perform background tasks
69
await updateLocalStorage(remoteMessage.data);
70
await sendAnalytics('background_message_received');
71
72
// Note: Avoid heavy processing that might timeout
73
});
74
75
// Modular API
76
import { getMessaging, setBackgroundMessageHandler } from '@react-native-firebase/messaging';
77
const messagingInstance = getMessaging();
78
79
setBackgroundMessageHandler(messagingInstance, async remoteMessage => {
80
console.log('Background message:', remoteMessage);
81
});
82
```
83
84
### Notification Opened Listener
85
86
Handles when the user taps a notification to open the app from a background state.
87
88
```typescript { .api }
89
/**
90
* Called when user presses a notification and app opens from background
91
* @param listener - Callback function receiving the RemoteMessage
92
* @returns Function to unsubscribe from notification opened events
93
*/
94
function onNotificationOpenedApp(listener: (message: RemoteMessage) => any): () => void;
95
```
96
97
**Usage Examples:**
98
99
```typescript
100
import messaging from '@react-native-firebase/messaging';
101
102
// Handle notification taps from background
103
const unsubscribe = messaging().onNotificationOpenedApp(remoteMessage => {
104
console.log('Notification caused app to open from background:', remoteMessage);
105
106
// Navigate to specific screen based on message data
107
if (remoteMessage.data?.screen) {
108
navigateToScreen(remoteMessage.data.screen);
109
}
110
});
111
112
// Modular API
113
import { getMessaging, onNotificationOpenedApp } from '@react-native-firebase/messaging';
114
const messagingInstance = getMessaging();
115
const unsubscribe = onNotificationOpenedApp(messagingInstance, remoteMessage => {
116
console.log('App opened from notification:', remoteMessage);
117
});
118
```
119
120
### Initial Notification
121
122
Retrieves the notification that caused the app to launch from a completely closed state.
123
124
```typescript { .api }
125
/**
126
* Get notification that opened the app from a quit state
127
* @returns Promise resolving to RemoteMessage or null if app wasn't opened by notification
128
*/
129
function getInitialNotification(): Promise<RemoteMessage | null>;
130
```
131
132
**Usage Examples:**
133
134
```typescript
135
import messaging from '@react-native-firebase/messaging';
136
137
// Check if app was opened by a notification
138
const initialNotification = await messaging().getInitialNotification();
139
140
if (initialNotification) {
141
console.log('App opened by notification:', initialNotification);
142
143
// Handle the initial notification
144
if (initialNotification.data?.deepLink) {
145
navigateToDeepLink(initialNotification.data.deepLink);
146
}
147
} else {
148
console.log('App opened normally');
149
}
150
151
// Modular API
152
import { getMessaging, getInitialNotification } from '@react-native-firebase/messaging';
153
const messagingInstance = getMessaging();
154
const initialNotification = await getInitialNotification(messagingInstance);
155
```
156
157
### Headless State Detection
158
159
Checks if the app is running in headless mode (launched in background by a data-only message).
160
161
```typescript { .api }
162
/**
163
* Returns whether root view is headless
164
* @returns Promise resolving to boolean indicating headless state
165
*/
166
function getIsHeadless(): Promise<boolean>;
167
```
168
169
**Usage Examples:**
170
171
```typescript
172
import messaging from '@react-native-firebase/messaging';
173
174
// Check if app is running headless
175
const isHeadless = await messaging().getIsHeadless();
176
177
if (isHeadless) {
178
console.log('App launched in background by FCM');
179
// Avoid UI operations in headless mode
180
} else {
181
console.log('App has active UI');
182
// Safe to perform UI operations
183
}
184
185
// Modular API
186
import { getMessaging, getIsHeadless } from '@react-native-firebase/messaging';
187
const messagingInstance = getMessaging();
188
const isHeadless = await getIsHeadless(messagingInstance);
189
```
190
191
## Message Lifecycle States
192
193
### Foreground State
194
- App is active and visible to user
195
- `onMessage` listener receives messages
196
- No automatic notification display
197
- Full React Native environment available
198
199
### Background State
200
- App is running but not visible
201
- `setBackgroundMessageHandler` processes messages
202
- Limited processing time available
203
- UI operations should be avoided
204
205
### Quit State
206
- App is completely closed
207
- Only `getInitialNotification` can retrieve launch message
208
- App launches normally when notification is tapped
209
210
## Message Processing Best Practices
211
212
1. **Foreground Messages**: Handle immediately, show custom UI
213
2. **Background Messages**: Keep processing lightweight, avoid timeouts
214
3. **Initial Notifications**: Check and handle during app initialization
215
4. **Error Handling**: Always wrap message handlers in try-catch blocks
216
5. **Memory Management**: Unsubscribe listeners when components unmount
217
218
## Common Message Scenarios
219
220
```typescript
221
// Complete message handling setup
222
import messaging from '@react-native-firebase/messaging';
223
224
// Background handler (called outside components)
225
messaging().setBackgroundMessageHandler(async remoteMessage => {
226
await processBackgroundMessage(remoteMessage);
227
});
228
229
// In your main component
230
useEffect(() => {
231
// Foreground messages
232
const unsubscribeForeground = messaging().onMessage(async remoteMessage => {
233
showInAppNotification(remoteMessage);
234
});
235
236
// Background to foreground
237
const unsubscribeOpened = messaging().onNotificationOpenedApp(remoteMessage => {
238
handleNotificationNavigation(remoteMessage);
239
});
240
241
// Check if launched by notification
242
messaging().getInitialNotification().then(remoteMessage => {
243
if (remoteMessage) {
244
handleNotificationNavigation(remoteMessage);
245
}
246
});
247
248
return () => {
249
unsubscribeForeground();
250
unsubscribeOpened();
251
};
252
}, []);
253
```