Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

cancelLocalNotifications() does not work on Android #2100

Closed
@jamesxabregas

Description

@jamesxabregas

I have tested this extensively to see if there was something wrong with the way I was excuting cancelLocalNotification() but it does not appear that this works when providing an id on Android. I am executing it exactly per the documentation.

After adding debug logging into the Anrdoid pacakge I believe I have found the root cause of the issue. In RNPushNotificationHelper.java the method cancelScheduledNotification(ReadableMap userInfo) tries to extract the id from the provided JSON map and then find the correct notification to cancel.

RNPushNotificationAttributes notificationAttributes = fromJson(notificationAttributesJson);
if (notificationAttributes.matches(userInfo)) {
cancelScheduledNotification(id);
}

The problem here is that the matches method in RNPushNotificationAttributes.java is being used incorrectly in this case. That method tries to match every element of the userInfo object with the notification it is iterating on which contains additional info such as the title, message etc. If the user has only provided the id attribute this always returns false.

public boolean matches(ReadableMap userInfo) {
try {
if(this.userInfo == null) {
return false;
}
JSONObject jsonObject = new JSONObject(this.userInfo);
ReadableMapKeySetIterator iterator = userInfo.keySetIterator();
while (iterator.hasNextKey()) {
String key = iterator.nextKey();
if (!jsonObject.has(key))
return false;
switch (userInfo.getType(key)) {
case Null: {
if (jsonObject.get(key) != null)
return false;
break;
}
case Boolean: {
if (userInfo.getBoolean(key) != jsonObject.getBoolean(key))
return false;
break;
}
case Number: {
if ((userInfo.getDouble(key) != jsonObject.getDouble(key)) && (userInfo.getInt(key) != jsonObject.getInt(key)))
return false;
break;
}
case String: {
if (!userInfo.getString(key).equals(jsonObject.getString(key)))
return false;
break;
}
case Map:
return false;//there are no maps in the jsonObject
case Array:
return false;//there are no arrays in the jsonObject
}
}
} catch(JSONException e) {
return false;
}
return true;
}

What is needed in this check is a simple method that matches the id's only.

For instance something like this in RNPushNotificationHelper.java:

RNPushNotificationAttributes notificationAttributes = fromJson(notificationAttributesJson);
if (notificationAttributes.idMatches(userInfo)) {
    cancelScheduledNotification(id);
}

and this in RNPushNotificationAttributes.java

public boolean idMatches(ReadableMap userInfo) {
try {
    if(this.userInfo == null || userInfo == null) {
        return false;
    }
        return this.id.equals(userInfo.getString("id"));
    } catch(Exception e) {
        return false;
    }
}

I am happy to submit a pull request for this issue. I am working on my own fork at the moment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions