Консоль Firebase: как указать click_action для уведомлений
Я реализовал Firebase и протестировал уведомления Firebase. Когда приложение находится на переднем плане, у меня нет проблем, я реализовал сервис, который расширяет FirebaseMessagingService и обрабатывает сообщение и данные в onMessageReceived
У меня проблемы, когда приложение работает в фоновом режиме. Я хотел бы отправить уведомление, которое открывает определенное действие и выполняет то, что я планирую сделать, а не просто открыть приложение.
Я сделал, как описано в руководстве по Firebase, но я не могу начать конкретное действие.
Здесь манифест:
<activity android:name=".BasicNotificationActivity">
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
А вот и консоль Firebase. Что мне нужно написать в этих полях, чтобы открыть "BasicNotificationActivity"?
3 ответа
Это дубликат этого вопроса: уведомления Firebase FCM полезная нагрузка click_action
Но ответ, который был принят автором этого вопроса, просто утверждает, что это невозможно с Firebase Console, но это - с легким обходным путем. Этот ответ diidu на тот же вопрос объясняет обходной путь, который я бы использовал.
ОБНОВИТЬ:
Чтобы уточнить его ответ:
Добавить вспомогательный класс (или реализовать startActivity()
метод как-то)
public class ClickActionHelper {
public static void startActivity(String className, Bundle extras, Context context){
Class cls;
try {
cls = Class.forName(className);
}catch(ClassNotFoundException e){
//means you made a wrong input in firebase console
}
Intent i = new Intent(context, cls);
i.putExtras(extras);
context.startActivity(i);
}
}
В launcher-активности вашего приложения вызовите метод для проверки любых новых намерений в onCreate()
а также onNewIntent()
(onNewIntent()
вызывается только вместо onCreate()
если активность запускается с одним верхним флагом):
@Override
protected void onCreate(Bundle bundle) {
[...]
checkIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
[...]
checkIntent(intent);
}
public void checkIntent(Intent intent) {
if (intent.hasExtra("click_action")) {
ClickActionHelper.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
}
}
И в onMessageReceived()
:
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (data.containsKey("click_action")) {
ClickActionHelper.startActivity(data.get("click_action"), null, this);
}
}
Чтобы отправить уведомление через консоль Firebase, укажите пару ключ-значение в качестве пользовательских данных, например:
Key: click_action
Value: <fully qualified classname of your activity>
Теперь, когда уведомление получено и нажата кнопка, оно откроет вашу активность. Если ваше приложение находится на переднем плане, оно также сразу же изменится на действие - вероятно, было бы хорошо спросить пользователя, хочет ли он перейти к этому действию или нет (показывая диалоговое окно в onMessageReceived()
).
Этому вопросу 2 года. Но все еще актуально. Вот как вы могли бы сделать это с помощью консоли Firebase (без `click_action).
Когда ваше приложение в фоновом режиме onMessageReceived
не будет называться. Но когда вы получаете уведомление, когда ваше приложение находится в фоновом режиме, вы получите Intent
вместе с пользовательскими данными, которые вы указываете в консоли Firebase.
Поэтому, когда пользователь нажимает на уведомление the intent
затем будет выполнен, чтобы открыть вашу активность запуска. Вы можете проверить данные по getIntent().hasExtra("key")
в вашей активности запуска. Где "key"
это любой ключ, который вы указываете в консоли.
Проверьте, есть ли у вас это "key"
затем вы можете сделать еще один Intent
и позвонить startActivity
Вот моя реализация,
На моем SplashActivity
> OnCreate
(Этот метод выглядит лучше, если у вас есть заставка в качестве действия запуска):
if (getIntent().hasExtra("key")){
Intent intent = new Intent(this, TargetActivity.class);
startActivity(intent);
finish();
} else {
startActivity(new Intent(this, MainActivity.class));
finish();
}
Это просто начнет TargetActivity
, Вы можете добавить любую функциональность к этому согласно вашему желанию:)
Я использовал handleIntent(Intent intent)
метод для обработки intent
и перейти к этому конкретному экрану. Ниже приведен мой код, который отлично работает, даже когда приложение находится в фоновом режиме:
FCMMessagingService.java который extends FCMMessagingService
@Override
public void handleIntent(Intent intent) {
super.handleIntent(intent);
Intent i = null;
String value_action = "";
if (intent.getExtras() != null) {
if (key.equals("click_action")) {
value_action = intent.getExtras().getString(key);
}
i = new Intent(FCMMessagingService.this, MainActivity.class);
i.putExtra("notificationFlag", value_action);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
PendingIntent pendingIntent = PendingIntent.getActivity(this, notifCount, i, PendingIntent.FLAG_ONE_SHOT);
final int icon = R.mipmap.logo;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
Notification notification;
notification = notificationBuilder.setSmallIcon(icon).setTicker(title)
.setAutoCancel(true)
.setContentTitle(title)
.setContentText(body)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.notification_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon))
.build();
notificationBuilder.setContentTitle(title);
notificationBuilder.setContentText(body);
notificationBuilder.setAutoCancel(true);
notificationBuilder.setSound(defaultSoundUri);
notificationBuilder.setContentIntent(pendingIntent);
notificationBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), icon));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setSmallIcon(R.mipmap.logo);
} else {
notificationBuilder.setSmallIcon(R.mipmap.logo);
}
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notifCount, notification);
}
У меня также есть проблема, как у вас, но я не могу получить правильный ответ, это факты, которые я знаю,
- onNewIntent
этот метод переопределения не работает, когда приложение работает в фоновом режиме, потому что действие по умолчанию - android.intent.action.MAIN
- Консоль Firebase
У консоли firebase недостаточно мощности для обработки click_action, что означает, что действие щелчка не может быть недоступно для приложения, когда приложение находится в фоновом режиме.
- CURL
Керл работает в фоновом режиме приложения, но не на переднем плане может быть, я не могу найти.
curl --header "Authorization: key=<Colud_Messaging_Server_Key_here>" --header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send -d "{\"to\":\"dwdfosu6SDs:APA91bFWxZZB2f8AOgP9MG504cy5AhFECHGbYFfIzVixoAfy-ErT0NYQrREg150CbKYBtk3Ywpu7WQuWsQhk-VmoOe-0iDK3ZgaFZNvYxDuixZB8zQp0zydoXhyrMosi5C4eyBb7Ai1z\",\"notification\": {\"title\": \"Click Action Message\",\"text\": \"Sample message\",\"click_action\":\"noti\",\"ticket_download\":\"noti\"}}"
Добавить минифест
<activity
android:name=".activity.TicketDownload"
android:exported="true">
<intent-filter>
<action android:name="noti" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
примечание: cloud_messaging_server_key - это параметр locate>cloudmessaging
если что-нибудь новые факты, пожалуйста, дайте мне знать.