diff --git a/packages/messaging/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java b/packages/messaging/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java index d57bde555a..cec3de6a0b 100644 --- a/packages/messaging/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java +++ b/packages/messaging/android/src/main/java/io/invertase/firebase/messaging/ReactNativeFirebaseMessagingModule.java @@ -29,6 +29,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap; import com.google.android.gms.tasks.Tasks; +import com.google.firebase.FirebaseApp; import com.google.firebase.messaging.FirebaseMessaging; import com.google.firebase.messaging.RemoteMessage; import io.invertase.firebase.common.ReactNativeFirebaseEventEmitter; @@ -120,8 +121,9 @@ public void setAutoInitEnabled(Boolean enabled, Promise promise) { } @ReactMethod - public void getToken(Promise promise) { - Tasks.call(getExecutor(), () -> Tasks.await(FirebaseMessaging.getInstance().getToken())) + public void getToken(String appName, String senderId, Promise promise) { + FirebaseMessaging messagingInstance = FirebaseApp.getInstance(appName).get(FirebaseMessaging.class); + Tasks.call(getExecutor(), () -> Tasks.await(messagingInstance.getToken())) .addOnCompleteListener( task -> { if (task.isSuccessful()) { @@ -133,11 +135,12 @@ public void getToken(Promise promise) { } @ReactMethod - public void deleteToken(Promise promise) { + public void deleteToken(String appName, String senderId, Promise promise) { + FirebaseMessaging messagingInstance = FirebaseApp.getInstance(appName).get(FirebaseMessaging.class); Tasks.call( getExecutor(), () -> { - Tasks.await(FirebaseMessaging.getInstance().deleteToken()); + Tasks.await(messagingInstance.deleteToken()); return null; }) .addOnCompleteListener( diff --git a/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m b/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m index 2c1ec12771..a0bc5b0d09 100644 --- a/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m +++ b/packages/messaging/ios/RNFBMessaging/RNFBMessagingModule.m @@ -107,7 +107,11 @@ - (NSDictionary *)constantsToExport { } } -RCT_EXPORT_METHOD(getToken : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { +RCT_EXPORT_METHOD(getToken + : (NSString *)appName + : (NSString *)senderId + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { #if !(TARGET_IPHONE_SIMULATOR) if ([UIApplication sharedApplication].isRegisteredForRemoteNotifications == NO) { [RNFBSharedUtils @@ -123,23 +127,30 @@ - (NSDictionary *)constantsToExport { #endif [[FIRMessaging messaging] - tokenWithCompletion:^(NSString *_Nullable token, NSError *_Nullable error) { - if (error) { - [RNFBSharedUtils rejectPromiseWithNSError:reject error:error]; - } else { - resolve(token); - } - }]; + retrieveFCMTokenForSenderID:senderId + completion:^(NSString *_Nullable token, NSError *_Nullable error) { + if (error) { + [RNFBSharedUtils rejectPromiseWithNSError:reject error:error]; + } else { + resolve(token); + } + }]; } -RCT_EXPORT_METHOD(deleteToken : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { - [[FIRMessaging messaging] deleteTokenWithCompletion:^(NSError *_Nullable error) { - if (error) { - [RNFBSharedUtils rejectPromiseWithNSError:reject error:error]; - } else { - resolve([NSNull null]); - } - }]; +RCT_EXPORT_METHOD(deleteToken + : (NSString *)appName + : (NSString *)senderId + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { + [[FIRMessaging messaging] deleteFCMTokenForSenderID:senderId + completion:^(NSError *_Nullable error) { + if (error) { + [RNFBSharedUtils rejectPromiseWithNSError:reject + error:error]; + } else { + resolve([NSNull null]); + } + }]; } RCT_EXPORT_METHOD(getAPNSToken : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) { diff --git a/packages/messaging/lib/index.d.ts b/packages/messaging/lib/index.d.ts index f0654f12fb..86188b035d 100644 --- a/packages/messaging/lib/index.d.ts +++ b/packages/messaging/lib/index.d.ts @@ -143,6 +143,25 @@ export namespace FirebaseMessagingTypes { threadId?: string; } + /** + * Options for `getToken()`, `deleteToken()` + */ + export interface TokenOptions { + /** + * The app name of the FirebaseApp instance. + * + * @platform android Android + */ + appName?: string; + + /** + * The senderID for a particular Firebase project. + * + * @platform ios iOS + */ + senderId?: string; + } + export interface Notification { /** * The notification title. @@ -579,8 +598,7 @@ export namespace FirebaseMessagingTypes { getDidOpenSettingsForNotification(): Promise; /** - * Returns an FCM token for this device. Optionally you can specify a custom authorized entity - * or scope to tailor tokens to your own use-case. + * Returns an FCM token for this device. Optionally you can specify a custom options to your own use-case. * * It is recommended you call this method on app start and update your backend with the new token. * @@ -602,8 +620,10 @@ export namespace FirebaseMessagingTypes { * fcmTokens: firebase.firestore.FieldValues.arrayUnion(fcmToken), * }); * ``` + * + * @param options Options to override senderId (iOS) and projectId (Android). */ - getToken(): Promise; + getToken(options?: TokenOptions): Promise; /** * Returns wether the root view is headless or not @@ -623,8 +643,10 @@ export namespace FirebaseMessagingTypes { * ```js * await firebase.messaging().deleteToken(); * ``` + * + * @param options Options to override senderId (iOS) and projectId (Android). */ - deleteToken(): Promise; + deleteToken(options?: TokenOptions): Promise; /** * When any FCM payload is received, the listener callback is called with a `RemoteMessage`. diff --git a/packages/messaging/lib/index.js b/packages/messaging/lib/index.js index b63b2f7f4b..5e053dc7ff 100644 --- a/packages/messaging/lib/index.js +++ b/packages/messaging/lib/index.js @@ -23,6 +23,7 @@ import { isIOS, isObject, isString, + isUndefined, } from '@react-native-firebase/app/lib/common'; import { createModuleNamespace, @@ -154,12 +155,34 @@ class FirebaseMessagingModule extends FirebaseModule { return this.native.getIsHeadless(); } - getToken() { - return this.native.getToken(); + getToken({ appName, senderId } = {}) { + if (!isUndefined(appName) && !isString(appName)) { + throw new Error("firebase.messaging().getToken(*) 'projectId' expected a string."); + } + + if (!isUndefined(senderId) && !isString(senderId)) { + throw new Error("firebase.messaging().getToken(*) 'senderId' expected a string."); + } + + return this.native.getToken( + appName || this.app.name, + senderId || this.app.options.messagingSenderId, + ); } - deleteToken() { - return this.native.deleteToken(); + deleteToken({ appName, senderId } = {}) { + if (!isUndefined(appName) && !isString(appName)) { + throw new Error("firebase.messaging().deleteToken(*) 'projectId' expected a string."); + } + + if (!isUndefined(senderId) && !isString(senderId)) { + throw new Error("firebase.messaging().deleteToken(*) 'senderId' expected a string."); + } + + return this.native.deleteToken( + appName || this.app.name, + senderId || this.app.options.messagingSenderId, + ); } onMessage(listener) {