Android 7.0 представил пользователям возможность введите текст прямо в уведомление, чтобы ответить на него без открытия приложения. Я использую проект реагировать-native-firebase, чтобы получать push-уведомления в моем приложении React Native.
Судя по документации, похоже, что эта функция поддерживается - в частности, AndroidNotification.addAction и AndroidAction.addRemoteInput, казалось бы, указывают на то, что это возможно.
Однако я не могу найти примеров того, как правильно реализовать эту функцию. Поддерживается ли эта функция в проекте React Native, использующем react-native-firebase?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Да, это возможно:
Обновите файл AndroidManifest.xml, включив в него следующее:
<receiver android:name = "io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported = "true">
<intent-filter>
<action android:name = "io.invertase.firebase.notifications.BackgroundAction"/>
</intent-filter>
</receiver>
<service android:name = "io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/>
Добавьте файл .js (например, backgroundMessaging.js), содержащий следующее:
import firebase from 'react-native-firebase'
export const backgroundMessageListener = async (message) => {
const notification = new firebase.notifications.Notification()
// TODO: Configure your notification here...
// https://rnfirebase.io/docs/v4.3.x/notifications/reference/AndroidAction
const action = new firebase.notifications.Android.Action('reply', 'ic_launcher', 'Reply')
action.setShowUserInterface(false)
// https://rnfirebase.io/docs/v4.0.x/notifications/reference/AndroidRemoteInput
const remoteInput = new firebase.notifications.Android.RemoteInput("input")
remoteInput.setLabel('Reply')
action.addRemoteInput(remoteInput)
notification.android.addAction(action)
firebase.notifications().displayNotification(notification)
return Promise.resolve()
}
export const backgroundActionHandler = async (notificationOpen) => {
if (notificationOpen.action === 'reply') {
// TODO: Handle the input entered by the user here...
console.info(notificationOpen);
}
return Promise.resolve();
};
Обновите index.js следующим образом:
import { backgroundMessageListener, backgroundActionHandler } from './backgroundMessaging'
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundMessage', () => backgroundMessageListener)
AppRegistry.registerHeadlessTask('RNFirebaseBackgroundNotificationAction', () => backgroundActionHandler);
Примечания:
В этом примере предполагается, что вы уже настроили react-native-firebase и следовали руководству по установке здесь. Функция backgroundMessageListener будет вызвана, когда ваше приложение не находится на переднем плане и получено уведомление о «данных». Получение уведомлений содержит примеры того, как выполнить дополнительную настройку, такую как запрос разрешения на получение уведомлений.
Я сделал это, и он работает отлично, за исключением случаев, когда я отправляю ввод в уведомлении, которое загружается навсегда, хотя я вызываю Promise.resolve()
@PalKerecsenyi, посмотри мой ответ.
Чтобы добавить к тому, что ответил @Donut, сейчас все немного изменилось.
AndroidManifest.xml (остается без изменений согласно @Donut)
<receiver android:name = "io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionReceiver" android:exported = "true">
<intent-filter>
<action android:name = "io.invertase.firebase.notifications.BackgroundAction"/>
</intent-filter>
</receiver>
<service android:name = "io.invertase.firebase.notifications.RNFirebaseBackgroundNotificationActionsService"/>
Рекомендуется добавить сюда идентификатор канала (например, app-local-notifications)
<meta-data
android:name = "com.google.firebase.messaging.default_notification_channel_id"
android:value = "@string/default_notification_channel_id"/>
Ваш backgroundMessaging.js теперь должен быть
import firebase from 'react-native-firebase'
const channelId = 'app-local-notifications'
export const backgroundMessageListener = async (message) => {
const channel = new firebase.notifications.Android.Channel(
channelId,
'Local Interactive Notifications',
firebase.notifications.Android.Importance.Max
).setDescription('Local Interactive Notifications');
firebase.notifications().android.createChannel(channel);
const localNotification = new firebase.notifications.Notification({
sound: 'default' //important
})
.setNotificationId(message.messageId)
.setTitle(message.data.title)
.setBody(message.data.body)
.android.setChannelId(channelId) //important
.android.setSmallIcon('ic_launcher')
.android.setPriority(firebase.notifications.Android.Priority.High); //important
const action = new firebase.notifications.Android.Action('reply', 'ic_launcher', 'Reply')
action.setShowUserInterface(false)
const remoteInput = new firebase.notifications.Android.RemoteInput("inputText")
remoteInput.setLabel('Message')
action.addRemoteInput(remoteInput)
localNotification.android.addAction(action)
firebase.notifications().displayNotification(localNotification).catch(err => console.info(err)); //important
}
export const backgroundActionHandler = async (notificationOpen) => {
if (notificationOpen && notificationOpen.notification) {
const action = notificationOpen.action;
const notificationId = notificationOpen.notification.notificationId;
if (action === "reply") {
console.info(notificationOpen)
} else {
console.info("unsupported action", action);
}
// hide the notification instead of Promise.resolve()
firebase.notifications().removeDeliveredNotification(notificationId); //important
}
};
На заметку:
1. Уведомление, отправленное через FCM, должно быть уведомлением data-only.
2. Приоритет уведомления должен быть «высоким».
3. Уведомление не должно занимать больше 60 секунд.
4. Требуется ChannelID.
5. Звук уведомления должен быть по умолчанию.
Не отображаются действия в Android, когда приложение находится в фоновом режиме или приложение закрыто. Не могли бы вы рассказать мне, как именно я могу добиться того же с помощью встроенной в реакцию Firebase. заранее спасибо