Merge pull request #1058 from dgruseck/master

[Android] Add the ability to remove notifications based on the tag
This commit is contained in:
Michael Diarmid 2018-07-20 11:35:08 +01:00 committed by GitHub
commit 321e4a2909
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 86 additions and 36 deletions

View File

@ -1,20 +1,19 @@
---
name: ⚠️ Bug/Issue report
about: Please provide as much detail as possible to help us with a bug or issue. Issues
name: ⚠️ Bug/Issue report
about: Please provide as much detail as possible to help us with a bug or issue. Issues
will be closed if they do not follow the template.
---
<!---
BEFORE YOU MAKE AN ISSUE
The issue list of this repo is exclusively for bug reports.
1) For feature requests, please use our Canny board: https://react-native-firebase.canny.io/feature-requests
2) For questions and support please use our Discord chat: https://discord.gg/C9aK28N or Stack Overflow: https://stackoverflow.com/questions/tagged/react-native-firebase
3) If this is a setup issue then please make sure you've correctly followed the setup guides, most setup issues such as 'duplicate dex files', 'default app has not been initialized' etc are all down to an incorrect setup as the guides haven't been correctly followed.
<!---
BEFORE YOU MAKE AN ISSUE
The issue list of this repo is exclusively for bug reports.
1) For feature requests, please use our Canny board: https://react-native-firebase.canny.io/feature-requests
2) For questions and support please use our Discord chat: https://discord.gg/C9aK28N or Stack Overflow: https://stackoverflow.com/questions/tagged/react-native-firebase
3) If this is a setup issue then please make sure you've correctly followed the setup guides, most setup issues such as 'duplicate dex files', 'default app has not been initialized' etc are all down to an incorrect setup as the guides haven't been correctly followed.
-->
### Issue
@ -23,7 +22,7 @@ The issue list of this repo is exclusively for bug reports.
### Environment
1. Application Target Platform:
1. Application Target Platform:
<!--- (e.g. iOS, Android, Both) --->
@ -47,14 +46,14 @@ The issue list of this repo is exclusively for bug reports.
<!--- (e.g. database, auth, messaging, analytics etc - or N/A if not applicable) --->
7. Are you using `typescript`?
7. Are you using `typescript`?
<!--- yes/no --->
---
Loving `react-native-firebase`? Please consider supporting them with any of the below:
- 👉 Back financially via [Open Collective](https://opencollective.com/react-native-firebase/donate)
- 👉 Follow [`React Native Firebase`](https://twitter.com/rnfirebase) and [`Invertase`](https://twitter.com/invertaseio) on Twitter
- 👉 Star this repo on GitHub ⭐️
* 👉 Back financially via [Open Collective](https://opencollective.com/react-native-firebase/donate)
* 👉 Follow [`React Native Firebase`](https://twitter.com/rnfirebase) and [`Invertase`](https://twitter.com/invertaseio) on Twitter
* 👉 Star this repo on GitHub ⭐️

View File

@ -49,7 +49,7 @@ All in all, RNFirebase provides much faster performance (~2x) over the web SDK a
| **Crashlytics**           | ❌ | ✅ | ✅ | ❌ |
| **Crash Reporting** | ✅ | ✅ | ✅ | ❌ |
| **Dynamic Links** | ❌ | ✅ | ✅ | ❌ |
| **[Functions Callable](https://firebase.googleblog.com/2018/04/launching-cloud-functions-for-firebase-1-0.html?m=1)**             |    |    | ✅ |    |
| **[Functions Callable](https://firebase.googleblog.com/2018/04/launching-cloud-functions-for-firebase-1-0.html?m=1)**             |    |    | ✅ |    |
| **Invites** | ❌ | ❌ | ✅ | ❌ |
| **Instance ID**          | ❌ | ❌ | **?** | ❌ |
| **Performance Monitoring** | ✅ | ✅ | ✅ | ❌ |
@ -64,11 +64,11 @@ All in all, RNFirebase provides much faster performance (~2x) over the web SDK a
> The table below shows the supported versions of React Native and the Firebase SDKs for different versions of `react-native-firebase`.
| | 2.2.x | 3.3.x | 4.0.x | 4.1.x | 4.2.x |
| -------------------- | -------- | -------- | -------- | -------- | -------- |
| React Native | 0.47 + | 0.50 + | 0.52 + | 0.52 + | 0.52-55.x |
| Firebase Android SDK | 11.0.0 + | 11.8.0 + | 12.0.0 + | 15.0.0 + | 15.0.0 + |
| Firebase iOS SDK | 4.0.0 + | 4.7.0 + | 4.11.0 + | 4.13.0 + | 5.0.0 + |
| | 2.2.x | 3.3.x | 4.0.x | 4.1.x | 4.2.x |
| -------------------- | -------- | -------- | -------- | -------- | --------- |
| React Native | 0.47 + | 0.50 + | 0.52 + | 0.52 + | 0.52-55.x |
| Firebase Android SDK | 11.0.0 + | 11.8.0 + | 12.0.0 + | 15.0.0 + | 15.0.0 + |
| Firebase iOS SDK | 4.0.0 + | 4.7.0 + | 4.11.0 + | 4.13.0 + | 5.0.0 + |
---

View File

@ -279,13 +279,18 @@ public class DisplayNotificationTask extends AsyncTask<Void, Void, Void> {
}
}
String tag = null;
if (android.containsKey("tag")) {
tag = android.getString("tag");
}
// Create the notification intent
PendingIntent contentIntent = createIntent(intentClass, notification, android.getString("clickAction"));
nb = nb.setContentIntent(contentIntent);
// Build the notification and send it
Notification builtNotification = nb.build();
notificationManager.notify(notificationId.hashCode(), builtNotification);
notificationManager.notify(tag, notificationId.hashCode(), builtNotification);
if (reactContext != null) {
Utils.sendEvent(reactContext, "notifications_notification_displayed", Arguments.fromBundle(notification));

View File

@ -17,6 +17,7 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.RemoteInput;
@ -153,7 +154,7 @@ public class RNFirebaseNotificationManager {
if (!notification.getBundle("schedule").containsKey("repeated")
|| !notification.getBundle("schedule").getBoolean("repeated")) {
String notificationId = notification.getString("notificationId");
preferences.edit().remove(notificationId).apply();;
preferences.edit().remove(notificationId).apply();
}
if (Utils.isAppInForeground(context)) {
@ -195,6 +196,15 @@ public class RNFirebaseNotificationManager {
promise.resolve(null);
}
public void removeDeliveredNotificationsByTag(String tag, Promise promise) {
StatusBarNotification[] statusBarNotifications = notificationManager.getActiveNotifications();
for (StatusBarNotification statusBarNotification : statusBarNotifications) {
if (statusBarNotification.getTag() == tag) {
notificationManager.cancel(statusBarNotification.getTag(), statusBarNotification.getId());
}
}
promise.resolve(null);
}
public void rescheduleNotifications() {
ArrayList<Bundle> bundles = getScheduledNotifications();

View File

@ -112,6 +112,11 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
notificationManager.removeDeliveredNotification(notificationId, promise);
}
@ReactMethod
public void removeDeliveredNotificationsByTag(String tag, Promise promise) {
notificationManager.removeDeliveredNotificationsByTag(tag, promise);
}
@ReactMethod
public void setBadge(int badge, Promise promise) {
// Store the badge count for later retrieval
@ -296,6 +301,7 @@ public class RNFirebaseNotifications extends ReactContextBaseJavaModule implemen
}
if (notification.getTag() != null) {
androidMap.putString("group", notification.getTag());
androidMap.putString("tag", notification.getTag());
}
notificationMap.putMap("android", androidMap);

View File

@ -372,7 +372,7 @@ RCT_EXPORT_METHOD(setBadge:(NSInteger) number
resolve(nil);
});
}
RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) {
jsReady = TRUE;
resolve(nil);
@ -487,11 +487,11 @@ RCT_EXPORT_METHOD(jsInitialised:(RCTPromiseResolveBlock)resolve rejecter:(RCTPro
NSString *identifier = a[@"identifier"];
NSURL *url = [NSURL fileURLWithPath:a[@"url"]];
NSMutableDictionary *attachmentOptions = nil;
if (a[@"options"]) {
NSDictionary *options = a[@"options"];
attachmentOptions = [[NSMutableDictionary alloc] init];
for (id key in options) {
if ([key isEqualToString:@"typeHint"]) {
attachmentOptions[UNNotificationAttachmentOptionsTypeHintKey] = options[key];

2
lib/index.d.ts vendored
View File

@ -1213,6 +1213,7 @@ declare module 'react-native-firebase' {
showWhen?: boolean;
smallIcon?: any;
sortKey?: string;
tag?: string;
ticker?: string;
timeoutAfter?: number;
usesChronometer?: boolean;
@ -1265,6 +1266,7 @@ declare module 'react-native-firebase' {
setShowWhen(showWhen: boolean): Notification;
setSmallIcon(icon: string, level?: number): Notification;
setSortKey(sortKey: string): Notification;
setTag(tag: string): Notification;
setTicker(ticker: string): Notification;
setTimeoutAfter(timeoutAfter: number): Notification;
setUsesChronometer(usesChronometer: boolean): Notification;

View File

@ -53,6 +53,7 @@ export default class AndroidNotification {
_smallIcon: SmallIcon;
_sortKey: string | void;
// TODO: style: Style; // Need to figure out if this can work
_tag: string | void;
_ticker: string | void;
_timeoutAfter: number | void;
_usesChronometer: boolean | void;
@ -106,6 +107,7 @@ export default class AndroidNotification {
this._showWhen = data.showWhen;
this._smallIcon = data.smallIcon;
this._sortKey = data.sortKey;
this._tag = data.tag;
this._ticker = data.ticker;
this._timeoutAfter = data.timeoutAfter;
this._usesChronometer = data.usesChronometer;
@ -238,6 +240,10 @@ export default class AndroidNotification {
return this._sortKey;
}
get tag(): ?string {
return this._tag;
}
get ticker(): ?string {
return this._ticker;
}
@ -615,6 +621,16 @@ export default class AndroidNotification {
return this._notification;
}
/**
*
* @param tag
* @returns {Notification}
*/
setTag(tag: string): Notification {
this._tag = tag;
return this._notification;
}
/**
*
* @param ticker
@ -719,6 +735,7 @@ export default class AndroidNotification {
smallIcon: this._smallIcon,
sortKey: this._sortKey,
// TODO: style: Style,
tag: this._tag,
ticker: this._ticker,
timeoutAfter: this._timeoutAfter,
usesChronometer: this._usesChronometer,

View File

@ -92,6 +92,20 @@ export default class AndroidNotifications {
return Promise.resolve();
}
removeDeliveredNotificationsByTag(tag: string): Promise<void> {
if (Platform.OS === 'android') {
if (typeof tag !== 'string') {
throw new Error(
`AndroidNotifications:removeDeliveredNotificationsByTag expects an 'string' but got type ${typeof tag}`
);
}
return getNativeModule(
this._notifications
).removeDeliveredNotificationsByTag(tag);
}
return Promise.resolve();
}
deleteChannelGroup(groupId: string): Promise<void> {
if (Platform.OS === 'android') {
if (typeof groupId !== 'string') {
@ -99,9 +113,7 @@ export default class AndroidNotifications {
`AndroidNotifications:deleteChannelGroup expects an 'string' but got type ${typeof groupId}`
);
}
return getNativeModule(this._notifications).deleteChannelGroup(
groupId
);
return getNativeModule(this._notifications).deleteChannelGroup(groupId);
}
return Promise.resolve();
}
@ -113,9 +125,7 @@ export default class AndroidNotifications {
`AndroidNotifications:deleteChannel expects an 'string' but got type ${typeof channelId}`
);
}
return getNativeModule(this._notifications).deleteChannel(
channelId
);
return getNativeModule(this._notifications).deleteChannel(channelId);
}
return Promise.resolve();
}

View File

@ -170,6 +170,7 @@ export type NativeAndroidNotification = {|
smallIcon: SmallIcon,
sortKey?: string,
// TODO: style: Style,
tag?: string,
ticker?: string,
timeoutAfter?: number,
usesChronometer?: boolean,