React Native:Android 25及以下后台HeadUp通知失效求助
Let's break down the issues in your code and walk through actionable fixes to get background head-up notifications working on older Android versions:
1. Fix Variable Name Collision
Your current listener reuses the notification variable, overwriting the incoming notification object. This can break property inheritance and lead to unexpected behavior. Rename the new notification instance to avoid conflicts:
this.notificationListener = firebase.notifications().onNotification((incomingNotification) => { console.log(incomingNotification) const newNotification = new firebase.notifications.Notification({ sound: 'default', show_in_foreground: true, }) // Rest of your code will use `newNotification` instead of reusing the parameter name });
2. Correct Vibration Configuration for API <26
Android 7.1 and below expects a vibration pattern array (delay followed by vibration duration), not a single number. Update your vibration setting to match the required format:
// Replace this line: // newNotification.android.setVibrate(1000) // With this valid vibration pattern: newNotification.android.setVibrate([0, 1000]) // 0ms delay before vibrating for 1000ms
3. Conditional Channel ID & Priority Handling
Channel IDs only work for API 26+. For older versions, skip the channel and enforce high-priority settings directly to trigger head-up notifications:
import { Platform } from 'react-native'; // Inside your notification listener if (Platform.Version >= 26) { newNotification.android.setChannelId('test-channel'); } else { // For API <26, explicitly set max priority and default sound/vibration newNotification.android.setPriority(firebase.notifications.Android.Priority.Max); newNotification.android.setDefaults( firebase.notifications.Android.Defaults.Sound | firebase.notifications.Android.Defaults.Vibrate ); }
4. Ensure Complete Property Copy from Incoming Notification
Make sure you're copying all critical properties from the incoming notification to avoid missing data that could prevent head-up display:
newNotification .setNotificationId(incomingNotification.notificationId || `notification-${Date.now()}`) .setTitle(incomingNotification.title) .setBody(incomingNotification.body) .android.setSmallIcon('ic_launcher') .setSound('default');
5. Verify Android Manifest Permissions & Setup
Ensure your AndroidManifest.xml includes permissions required for vibration and background notifications:
<!-- Required for vibration functionality --> <uses-permission android:name="android.permission.VIBRATE" /> <!-- Required for FCM communication --> <uses-permission android:name="android.permission.INTERNET" />
Also confirm your Firebase Messaging services are correctly registered (this is usually set up by react-native-firebase, but double-check):
<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name="io.invertase.firebase.messaging.RNFirebaseInstanceIdService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT" /> </intent-filter> </service>
6. Ensure FCM Payload Includes High Priority
For background notifications on API <26, your FCM payload must include the priority: "high" flag to tell the system to trigger a head-up notification:
{ "to": "YOUR_DEVICE_TOKEN", "notification": { "title": "Test Head-Up", "body": "This should show as head-up on Android 7.1", "sound": "default", "priority": "high" }, "data": { "customKey": "customValue" } }
Updated Listener Code (Putting It All Together)
import { Platform } from 'react-native'; import firebase from 'react-native-firebase'; // Initialize notification channel once (e.g., in componentDidMount) const initNotificationChannel = () => { if (Platform.Version >= 26) { const channel = new firebase.notifications.Android.Channel( 'test-channel', 'Test Channel', firebase.notifications.Android.Importance.Max ); channel.setDescription('My apps test channel'); firebase.notifications().android.createChannel(channel); } }; componentDidMount() { initNotificationChannel(); this.notificationListener = firebase.notifications().onNotification((incomingNotification) => { console.log('Incoming notification:', incomingNotification); const newNotification = new firebase.notifications.Notification({ sound: 'default', show_in_foreground: true, }) .setNotificationId(incomingNotification.notificationId || `notification-${Date.now()}`) .setTitle(incomingNotification.title) .setBody(incomingNotification.body) .setSound('default') .android.setSmallIcon('ic_launcher'); if (Platform.Version >= 26) { newNotification.android.setChannelId('test-channel'); } else { newNotification.android.setPriority(firebase.notifications.Android.Priority.Max); newNotification.android.setVibrate([0, 1000]); newNotification.android.setDefaults( firebase.notifications.Android.Defaults.Sound | firebase.notifications.Android.Defaults.Vibrate ); } firebase.notifications().displayNotification(newNotification); }); } componentWillUnmount() { this.notificationListener(); // Clean up the listener to avoid memory leaks }
These changes should ensure your head-up notifications work consistently across all Android versions, including background scenarios on API 25 and below.
内容的提问来源于stack exchange,提问作者Yash Vaghela

