How to push firebase notification only when CheckB

2019-07-30 08:43发布

I am using Firebase notifications in order to notify users about new data posted to the app. I'm following the example given here: https://github.com/firebase/quickstart-android/tree/master/messaging

Although, I am also providing preference to the user. They should get notified only when they chose to get notified by checking the CheckBoxPreference.

I have set the CheckBoxPreference and also the onPreferenceChangeListener successfully. The problem is that user is getting the notification even when the CheckBox is unchecked.

Here's what I have done in SettingsActivity:

public class SettingsActivity extends PreferenceActivity {

    private AppCompatDelegate mDelegate;

    Preference myPref;

    boolean isChecked = true;

    private static final String TAG = "SettingsActivity";

    public static final String RECEIVE_NOTIFS = "receiveNotifications";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        getDelegate().installViewFactory();
        getDelegate().onCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        myPref = (CheckBoxPreference) findPreference(RECEIVE_NOTIFS);
        myPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object o) {
                isChecked = Boolean.valueOf(o.toString());
                if (isChecked) {
                    Toast.makeText(getBaseContext(), "Checked", Toast.LENGTH_SHORT).show();
                    if (getIntent().getExtras() != null) {
                        String remoteMessage = getIntent().getExtras().getString("remoteMessage");
                        sendNotification(remoteMessage);
                    } else {
                        Toast.makeText(getBaseContext(), "Error!", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    Toast.makeText(getBaseContext(), "Unchecked", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        });

    }

    public void sendNotification(String messageBody) {
        Intent intent = new Intent(this, SettingsActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("FCM Message")
                .setContentText(messageBody)
                .setAutoCancel(true)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
    }

I have clearly specified in above code that notification should be sent only when CheckBoxPreference is checked.

Here's MyFirebaseMessagingService.java file's code:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = "MyFirebaseMsgService";

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    // [START receive_message]
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        // TODO(developer): Handle FCM messages here.
        // If the application is in the foreground handle both data and notification messages here.
        // Also if you intend on generating your own notifications as a result of a received FCM
        // message, here is where that should be initiated. See sendNotification method below.
        Log.d(TAG, "From: " + remoteMessage.getFrom());
        Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());

        Intent intent = new Intent(this, SettingsActivity.class);
        intent.putExtra("remoteMessage", remoteMessage.getNotification().getBody());
        startActivity(intent);
    }
    // [END receive_message]

}

What I am doing here is I am sending remoteMessage as an Intent to the SettingsActivity and using it in sendNotification() method there.

So, clearly what I want is I want the user to get notified only when they have chosen to be by checking the CheckBoxPreference.

Please let me what am I doing wrong here.

1条回答
Animai°情兽
2楼-- · 2019-07-30 09:16

When you use Firebase Notifications, the message that is sent is a notification message. When the app is in the foreground, your code will be handling the notification. But when the app is backgrounded, the default notification center will handle it. And since the notification center knows nothing of your checkbox, it will always display the notification.

See this answer to an issue on the quickstart repo for the best explanation I've seen so far: https://github.com/firebase/quickstart-android/issues/8#issuecomment-221039175

You have a few options to get your logic working:

  • don't send a notification if the user hasn't checked the box. So instead of suppressing the display, simply don't send it. For example, you could probably send to a topic to which only users that have opted in subscribe.

  • send a data message instead of a notification. This ensures that your code will always be invoked, even when the app is backgrounded. See the documentation on Notifications and data in the message payload for more on the difference between notifications and data messages.

Related questions:

查看更多
登录 后发表回答