在安卓上禁用Firebase通知 - 我想在安卓客户端禁用Firebase通知。

17
我正在使用 Firebase 控制台向用户发送通知。但是我想让用户禁用通知。如何禁用通知?
只有当应用程序在前台时,我才能通过 FirebaseMessagingService 处理(并停止)通知。但是当应用程序在后台时,无法停止通知。
5个回答

14

我还不能发表评论,但是racs的评论对我帮助很大。

实际上,Firebase文档建议使用数据推送而不是通知,如果你想要完全控制它的处理方式:firebase.google.com/docs/cloud-messaging/… - 引用:"当您希望FCM代表您的客户端应用程序处理显示通知时,请使用通知。当您希望您的应用程序在Android客户端应用程序上处理显示或处理消息时,请使用数据消息..."

因此,基本上我将推送通知请求的主体从:

{
   "data": {
       "type" : "mytype"
    },
    "notification": {
        "title": "My Title",
        "body": "My Notification Message"
    },
    "to": "/topics/all"
}

收件人:

{
   "data": {
       "type" : "mytype",
       "title": "My Title",
       "body": "My Notification Message"
    },
    "to": "/topics/all"
}

现在我的应用即使在后台也会调用onMessageReceived()方法,我只是更改了方法以使用推送数据中获取的通知标题和消息。


有没有办法使用这种方法,使得推送通知被视为通知而不仅仅是 Firebase 仪表板中的数据? - Benoit
@Benoit 使用fcm控制台将始终发送一个通知对象。 - Alvin Rusli
@AlvinRusli 的回答真的很有帮助,当应用程序被杀死/关闭时,我该如何处理接收到的数据? - Mehdi Dehghani
谢谢,这里是文档 https://firebase.google.com/docs/cloud-messaging/concept-options - FindOutIslamNow

6

不确定为什么会发生这种情况(可能是代码片段?),但有一个重量级的终极解决方案:在清单中定义自己的c2dm接收器,并将优先级设置为高(>0),然后停止处理通知。

GCM消息被处理为有序广播,因此您可以通过调用此方法来停止处理链:

https://developer.android.com/reference/android/content/BroadcastReceiver.html#abortBroadcast()

如果您的接收器没有执行任何操作,那么下一个接收器将进行处理,这将是 Firebase 接收器。
请注意:Firebase 会为远程配置更改发送推送通知。因此,如果您使用远程配置,则不建议抑制任何数据推送。

1
实际上,Firebase文档建议使用数据推送而不是通知,如果你想完全控制它的处理方式:https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages - 引用:“当您希望FCM代表您的客户端应用程序处理显示通知时,请使用通知。当您希望您的应用程序处理Android客户端应用程序上的显示或处理消息时,请使用数据消息...” - racs
谢谢。通过数据推送(通过POST请求),即使应用程序在后台,我也能够处理通知。现在,如何在不指定JSON文件中每个设备的令牌的情况下向所有设备发送数据?通过Firebase控制台可以指定“用户段”,但如果我不在JSON文件中指定“to”元素,则会收到错误400。 - martinodecarlo
我不是这个主题的专家,但据我所知,当您进行数据推送时,基本上会完全跳过Firebase功能。因此,无法发送到主题订阅者或分析。在这种情况下,FB充当GCM的中继,并且根本不与发送的数据交互。 - racs
似乎可以将数据发送到主题:https://firebase.google.com/docs/cloud-messaging/topic-messaging#sending_topic_messages_from_the_server 您可以将每个设备注册到一个主题并向该主题发送数据推送,因此无需自己跟踪设备令牌。 - racs

3
我遇到了这个问题,然后通过以下代码解决了它: 启用Firebase通知:
FirebaseInstanceId.getInstance().getToken();

禁用 Firebase 通知: deleteInstanceId() 是一个阻塞调用。它不能在主线程上调用。

FirebaseInstanceId.getInstance().deleteInstanceId();

方法 FirebaseInstanceId.getInstance().deleteInstanceId(); 在哪里设置? - ARR.s
我使用AsyncTask,并在doInBackground中放置了 FirebaseInstanceId.getInstance().deleteInstanceId(); - Better
请注意,FirebaseInstanceId已被弃用(整个IID包已被弃用),但是Installations包已经接管了它的职责,FirebaseInstallations.getInstance().delete()应该可以解决问题(https://firebase.google.com/docs/reference/android/com/google/firebase/installations/FirebaseInstallations#delete())。 - Mike Hardy

3
我遇到了相同的问题。我使用subscribeToTopic API订阅通知。
FirebaseMessaging.getInstance().subscribeToTopic("APP");

我发现另一个APIunsubscribeFromTopic用于取消订阅。

FirebaseMessaging.getInstance().unsubscribeFromTopic("APP");

也许对于使用主题通知的应用程序来说会很有用。它不会在前台和后台接收通知。

2

您可以使用 Firebase 处理来自所有不同服务的所有推送事件。首先,创建 YouUniversalFCM extends WakefulBroadcastReceiver

例如:

public class YourUniversalFCM extends WakefulBroadcastReceiver {

    private static final String ACTION_REGISTRATION
        = "com.google.android.c2dm.intent.REGISTRATION";
    private static final String ACTION_RECEIVE
        = "com.google.android.c2dm.intent.RECEIVE";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        for (String key : intent.getExtras().keySet()) {
            Log.d(
                    "TAG",
                    "{UniversalFCM}->onReceive: key->"
                            + key + ", value->" + intent.getExtras().get(key)
            );
        }
        switch (action) {
            case ACTION_REGISTRATION:
                // TODO: 2016-08-06
                break;

            case ACTION_RECEIVE:
                // TODO: 2016-08-06
                break;

            default:
        }

        abortBroadcast();
    }
}

下一个步骤是在AndroidManifest.xml中进行。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<application
    ...>

    ...

    <receiver
        android:name=".fcm.receivers.UniversalFCM"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE"/>
            <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
            <category android:name="YOUR_PACKAGE"/>
        </intent-filter>
    </receiver>

</application>

请将YOUR_PACKAGE替换为您的应用程序包。就这样。 如果您想订阅其他推送服务,则必须添加YourTokenService

public class YourTokenService extends FirebaseInstanceIdService {
    @Override
    public void onTokenRefresh() {
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
        L.d(TokenService.class, "onTokenRefresh() Refreshed token: " + refreshedToken);
        // TODO: 2016-08-06
        super.onTokenRefresh();
    }
}

并在 AndroidManifest.xml 中声明。

<service android:name="YourTokenService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
</service>

WakefulBroadcastReceiver 现已被弃用,请避免使用此方法并参考 Alvin Rusli 的回答。 - Alex Timonin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接