@fishonfire/bubbles-expo 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -70,6 +70,8 @@ Plugin options:
70
70
 
71
71
  For Android remote display, backend payloads must use the same `android.notification.channel_id` as `defaultChannelId`. The plugin writes Firebase's default-channel manifest metadata, and the package creates the actual Android notification channel when `BubblesNotificationsProvider`, `getNotificationPermissions()`, or `ensureDefaultNotificationChannel()` runs. On a fresh install, the app must be opened at least once before remote notifications can reliably use this configured channel; otherwise Android/Firebase may fall back to its own default behavior before JavaScript has created the channel.
72
72
 
73
+ Device registration uses the Firebase Installation ID (FID) as the push registration identifier. The package does not call Firebase Messaging's deprecated `getToken()` path for Bubbles device sync; the same FID value is sent as both `push_token` and `fid`. On Android, the config plugin also opts into FID-based Firebase Messaging registration and installs native startup code that calls `FirebaseMessaging.getInstance().register()` automatically.
74
+
73
75
  ## Background registration
74
76
 
75
77
  Register the package-owned background notification handlers once from your app entrypoint:
@@ -162,7 +164,7 @@ export function EnableNotificationsButton() {
162
164
  }
163
165
  ```
164
166
 
165
- `useBubblesNotifications()` also exposes `addDeviceAttribute`, `deviceId`, `pushToken`, `permissionStatus`, `notificationsEnabled`, `tokenType`, and `error`.
167
+ `useBubblesNotifications()` also exposes `addDeviceAttribute`, `deviceId`, `pushToken`, `permissionStatus`, `notificationsEnabled`, `tokenType`, and `error`. When notifications are enabled, `pushToken` is the Firebase Installation ID and `tokenType` is `"fid"`.
166
168
 
167
169
  If your app already requested notification permissions, call `registerDevice({ requestPermissions: false })`.
168
170
 
package/dist/index.d.mts CHANGED
@@ -212,7 +212,7 @@ declare function ensureNotificationPermissions(options?: GetNotificationPermissi
212
212
 
213
213
  type SupportedPlatform = 'android' | 'ios';
214
214
 
215
- type NativeTokenType = 'fcm';
215
+ type NativeTokenType = 'fid';
216
216
  type GetDeviceTokenOptions = GetNotificationPermissionsOptions;
217
217
  interface DeviceTokenResult {
218
218
  platform: SupportedPlatform;
package/dist/index.d.ts CHANGED
@@ -212,7 +212,7 @@ declare function ensureNotificationPermissions(options?: GetNotificationPermissi
212
212
 
213
213
  type SupportedPlatform = 'android' | 'ios';
214
214
 
215
- type NativeTokenType = 'fcm';
215
+ type NativeTokenType = 'fid';
216
216
  type GetDeviceTokenOptions = GetNotificationPermissionsOptions;
217
217
  interface DeviceTokenResult {
218
218
  platform: SupportedPlatform;
package/dist/index.js CHANGED
@@ -1418,27 +1418,28 @@ function registerBubblesBackgroundHandlers() {
1418
1418
  }
1419
1419
 
1420
1420
  // src/runtime/tokens.ts
1421
- var import_messaging2 = require("@react-native-firebase/messaging");
1422
1421
  var import_react_native4 = require("react-native");
1423
- async function getFirebaseMessagingToken(platform) {
1422
+
1423
+ // src/runtime/installations.ts
1424
+ var import_installations = require("@react-native-firebase/installations");
1425
+ async function getFirebaseInstallationId(platform) {
1424
1426
  try {
1425
- const messagingInstance = (0, import_messaging2.getMessaging)();
1426
- if (!(0, import_messaging2.isDeviceRegisteredForRemoteMessages)(messagingInstance)) {
1427
- await (0, import_messaging2.registerDeviceForRemoteMessages)(messagingInstance);
1428
- }
1429
- const token = await (0, import_messaging2.getToken)(messagingInstance);
1427
+ const installationsInstance = (0, import_installations.getInstallations)();
1428
+ const installationId = await (0, import_installations.getId)(installationsInstance);
1430
1429
  return getRequiredNonEmptyStringFromSource(
1431
- token,
1432
- `${platform} FCM token from Firebase Messaging`
1430
+ installationId,
1431
+ `${platform} Firebase installation id from Firebase Installations`
1433
1432
  );
1434
1433
  } catch (error) {
1435
1434
  const reason = getErrorMessage(error);
1436
- const platformSpecificSetupHint = platform === "ios" ? " On iOS, also ensure Firebase APNs setup is complete and `expo.ios.googleServicesFile` is configured." : " On Android, ensure `google-services.json` is configured and the native app has been rebuilt.";
1435
+ const platformSpecificSetupHint = platform === "ios" ? " On iOS, ensure `expo.ios.googleServicesFile` is configured and the native app has been rebuilt." : " On Android, ensure `expo.android.googleServicesFile` is configured and the native app has been rebuilt.";
1437
1436
  failWithBubblesError(
1438
- `Failed to get a ${platform} FCM token from Firebase Messaging. Ensure "@react-native-firebase/app" and "@react-native-firebase/messaging" are installed, the Expo app includes the "@react-native-firebase/messaging" config plugin, and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
1437
+ `Failed to get a ${platform} Firebase installation id from Firebase Installations. Ensure "@react-native-firebase/app" and "@react-native-firebase/installations" are installed and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
1439
1438
  );
1440
1439
  }
1441
1440
  }
1441
+
1442
+ // src/runtime/tokens.ts
1442
1443
  async function getDeviceRegistrationState(options) {
1443
1444
  const platform = getSupportedPlatform(import_react_native4.Platform.OS);
1444
1445
  const permissions = await getNotificationPermissions(options);
@@ -1453,10 +1454,10 @@ async function getDeviceRegistrationState(options) {
1453
1454
  notificationsEnabled: false
1454
1455
  };
1455
1456
  }
1456
- const token = await getFirebaseMessagingToken(platform);
1457
+ const token = await getFirebaseInstallationId(platform);
1457
1458
  return {
1458
1459
  platform,
1459
- tokenType: "fcm",
1460
+ tokenType: "fid",
1460
1461
  token,
1461
1462
  permissionStatus,
1462
1463
  notificationsEnabled: true
@@ -1469,7 +1470,7 @@ async function getDeviceToken(options) {
1469
1470
  }
1470
1471
  return {
1471
1472
  platform: registrationState.platform,
1472
- tokenType: "fcm",
1473
+ tokenType: "fid",
1473
1474
  token: registrationState.token
1474
1475
  };
1475
1476
  }
@@ -1683,7 +1684,7 @@ async function prepareBubblesNotificationPresentation(options) {
1683
1684
  }
1684
1685
 
1685
1686
  // src/runtime/foreground-message-observer.ts
1686
- var import_messaging3 = require("@react-native-firebase/messaging");
1687
+ var import_messaging2 = require("@react-native-firebase/messaging");
1687
1688
  var import_react_native5 = require("react-native");
1688
1689
  function supportsFirebaseForegroundMessages() {
1689
1690
  return import_react_native5.Platform.OS === "android" || import_react_native5.Platform.OS === "ios";
@@ -1703,8 +1704,8 @@ function observeBubblesForegroundMessages() {
1703
1704
  return () => {
1704
1705
  };
1705
1706
  }
1706
- const unsubscribe = (0, import_messaging3.onMessage)(
1707
- (0, import_messaging3.getMessaging)(),
1707
+ const unsubscribe = (0, import_messaging2.onMessage)(
1708
+ (0, import_messaging2.getMessaging)(),
1708
1709
  (remoteMessage) => {
1709
1710
  void handleFirebaseForegroundMessage(remoteMessage).catch(
1710
1711
  (error) => {
@@ -1721,25 +1722,6 @@ function observeBubblesForegroundMessages() {
1721
1722
  };
1722
1723
  }
1723
1724
 
1724
- // src/runtime/installations.ts
1725
- var import_installations = require("@react-native-firebase/installations");
1726
- async function getFirebaseInstallationId(platform) {
1727
- try {
1728
- const installationsInstance = (0, import_installations.getInstallations)();
1729
- const installationId = await (0, import_installations.getId)(installationsInstance);
1730
- return getRequiredNonEmptyStringFromSource(
1731
- installationId,
1732
- `${platform} Firebase installation id from Firebase Installations`
1733
- );
1734
- } catch (error) {
1735
- const reason = getErrorMessage(error);
1736
- const platformSpecificSetupHint = platform === "ios" ? " On iOS, ensure `expo.ios.googleServicesFile` is configured and the native app has been rebuilt." : " On Android, ensure `expo.android.googleServicesFile` is configured and the native app has been rebuilt.";
1737
- failWithBubblesError(
1738
- `Failed to get a ${platform} Firebase installation id from Firebase Installations. Ensure "@react-native-firebase/app" and "@react-native-firebase/installations" are installed and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
1739
- );
1740
- }
1741
- }
1742
-
1743
1725
  // src/runtime/transport.ts
1744
1726
  function observeBubblesForegroundRemoteMessages() {
1745
1727
  return observeBubblesForegroundMessages();
@@ -1747,9 +1729,6 @@ function observeBubblesForegroundRemoteMessages() {
1747
1729
  async function getBubblesDeviceRegistrationState(options) {
1748
1730
  return getDeviceRegistrationState(options);
1749
1731
  }
1750
- async function getBubblesInstallationId(platform) {
1751
- return getFirebaseInstallationId(platform);
1752
- }
1753
1732
 
1754
1733
  // src/runtime/sync-device.ts
1755
1734
  var BubblesNotificationsSyncError = class extends Error {
@@ -1812,7 +1791,7 @@ async function syncDeviceRegistrationState(options) {
1812
1791
  options.registrationState
1813
1792
  );
1814
1793
  try {
1815
- const installationId = options.registrationState.notificationsEnabled ? await getBubblesInstallationId(options.registrationState.platform) : null;
1794
+ const installationId = options.registrationState.notificationsEnabled ? options.registrationState.token : null;
1816
1795
  const syncResult = await syncBubblesDevice({
1817
1796
  apiBaseUrl,
1818
1797
  appId: options.appId,
package/dist/index.mjs CHANGED
@@ -52,32 +52,28 @@ import {
52
52
  } from "./chunk-3BAGWXHY.mjs";
53
53
 
54
54
  // src/runtime/tokens.ts
55
- import {
56
- getMessaging,
57
- getToken,
58
- isDeviceRegisteredForRemoteMessages,
59
- registerDeviceForRemoteMessages
60
- } from "@react-native-firebase/messaging";
61
55
  import { Platform } from "react-native";
62
- async function getFirebaseMessagingToken(platform) {
56
+
57
+ // src/runtime/installations.ts
58
+ import { getId, getInstallations } from "@react-native-firebase/installations";
59
+ async function getFirebaseInstallationId(platform) {
63
60
  try {
64
- const messagingInstance = getMessaging();
65
- if (!isDeviceRegisteredForRemoteMessages(messagingInstance)) {
66
- await registerDeviceForRemoteMessages(messagingInstance);
67
- }
68
- const token = await getToken(messagingInstance);
61
+ const installationsInstance = getInstallations();
62
+ const installationId = await getId(installationsInstance);
69
63
  return getRequiredNonEmptyStringFromSource(
70
- token,
71
- `${platform} FCM token from Firebase Messaging`
64
+ installationId,
65
+ `${platform} Firebase installation id from Firebase Installations`
72
66
  );
73
67
  } catch (error) {
74
68
  const reason = getErrorMessage(error);
75
- const platformSpecificSetupHint = platform === "ios" ? " On iOS, also ensure Firebase APNs setup is complete and `expo.ios.googleServicesFile` is configured." : " On Android, ensure `google-services.json` is configured and the native app has been rebuilt.";
69
+ const platformSpecificSetupHint = platform === "ios" ? " On iOS, ensure `expo.ios.googleServicesFile` is configured and the native app has been rebuilt." : " On Android, ensure `expo.android.googleServicesFile` is configured and the native app has been rebuilt.";
76
70
  failWithBubblesError(
77
- `Failed to get a ${platform} FCM token from Firebase Messaging. Ensure "@react-native-firebase/app" and "@react-native-firebase/messaging" are installed, the Expo app includes the "@react-native-firebase/messaging" config plugin, and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
71
+ `Failed to get a ${platform} Firebase installation id from Firebase Installations. Ensure "@react-native-firebase/app" and "@react-native-firebase/installations" are installed and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
78
72
  );
79
73
  }
80
74
  }
75
+
76
+ // src/runtime/tokens.ts
81
77
  async function getDeviceRegistrationState(options) {
82
78
  const platform = getSupportedPlatform(Platform.OS);
83
79
  const permissions = await getNotificationPermissions(options);
@@ -92,10 +88,10 @@ async function getDeviceRegistrationState(options) {
92
88
  notificationsEnabled: false
93
89
  };
94
90
  }
95
- const token = await getFirebaseMessagingToken(platform);
91
+ const token = await getFirebaseInstallationId(platform);
96
92
  return {
97
93
  platform,
98
- tokenType: "fcm",
94
+ tokenType: "fid",
99
95
  token,
100
96
  permissionStatus,
101
97
  notificationsEnabled: true
@@ -108,7 +104,7 @@ async function getDeviceToken(options) {
108
104
  }
109
105
  return {
110
106
  platform: registrationState.platform,
111
- tokenType: "fcm",
107
+ tokenType: "fid",
112
108
  token: registrationState.token
113
109
  };
114
110
  }
@@ -323,7 +319,7 @@ async function prepareBubblesNotificationPresentation(options) {
323
319
 
324
320
  // src/runtime/foreground-message-observer.ts
325
321
  import {
326
- getMessaging as getMessaging2,
322
+ getMessaging,
327
323
  onMessage
328
324
  } from "@react-native-firebase/messaging";
329
325
  import { Platform as Platform2 } from "react-native";
@@ -346,7 +342,7 @@ function observeBubblesForegroundMessages() {
346
342
  };
347
343
  }
348
344
  const unsubscribe = onMessage(
349
- getMessaging2(),
345
+ getMessaging(),
350
346
  (remoteMessage) => {
351
347
  void handleFirebaseForegroundMessage(remoteMessage).catch(
352
348
  (error) => {
@@ -363,25 +359,6 @@ function observeBubblesForegroundMessages() {
363
359
  };
364
360
  }
365
361
 
366
- // src/runtime/installations.ts
367
- import { getId, getInstallations } from "@react-native-firebase/installations";
368
- async function getFirebaseInstallationId(platform) {
369
- try {
370
- const installationsInstance = getInstallations();
371
- const installationId = await getId(installationsInstance);
372
- return getRequiredNonEmptyStringFromSource(
373
- installationId,
374
- `${platform} Firebase installation id from Firebase Installations`
375
- );
376
- } catch (error) {
377
- const reason = getErrorMessage(error);
378
- const platformSpecificSetupHint = platform === "ios" ? " On iOS, ensure `expo.ios.googleServicesFile` is configured and the native app has been rebuilt." : " On Android, ensure `expo.android.googleServicesFile` is configured and the native app has been rebuilt.";
379
- failWithBubblesError(
380
- `Failed to get a ${platform} Firebase installation id from Firebase Installations. Ensure "@react-native-firebase/app" and "@react-native-firebase/installations" are installed and Firebase is configured for this platform.${platformSpecificSetupHint} Original error: ${reason}`
381
- );
382
- }
383
- }
384
-
385
362
  // src/runtime/transport.ts
386
363
  function observeBubblesForegroundRemoteMessages() {
387
364
  return observeBubblesForegroundMessages();
@@ -389,9 +366,6 @@ function observeBubblesForegroundRemoteMessages() {
389
366
  async function getBubblesDeviceRegistrationState(options) {
390
367
  return getDeviceRegistrationState(options);
391
368
  }
392
- async function getBubblesInstallationId(platform) {
393
- return getFirebaseInstallationId(platform);
394
- }
395
369
 
396
370
  // src/runtime/sync-device.ts
397
371
  var BubblesNotificationsSyncError = class extends Error {
@@ -454,7 +428,7 @@ async function syncDeviceRegistrationState(options) {
454
428
  options.registrationState
455
429
  );
456
430
  try {
457
- const installationId = options.registrationState.notificationsEnabled ? await getBubblesInstallationId(options.registrationState.platform) : null;
431
+ const installationId = options.registrationState.notificationsEnabled ? options.registrationState.token : null;
458
432
  const syncResult = await syncBubblesDevice({
459
433
  apiBaseUrl,
460
434
  appId: options.appId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishonfire/bubbles-expo",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Expo config plugin, explicit background registration API, and React provider for Bubbles notifications.",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const config_1 = require("./config");
7
7
  const with_firebase_messaging_manifest_1 = __importDefault(require("./with-firebase-messaging-manifest"));
8
+ const with_firebase_messaging_registration_1 = __importDefault(require("./with-firebase-messaging-registration"));
8
9
  const with_expo_notifications_1 = __importDefault(require("./with-expo-notifications"));
9
10
  const with_runtime_defaults_1 = __importDefault(require("./with-runtime-defaults"));
10
11
  const with_rnfirebase_disable_spm_1 = __importDefault(require("./with-rnfirebase-disable-spm"));
@@ -13,6 +14,7 @@ const withBubblesNotificationsExpo = (config, input) => {
13
14
  config = (0, with_runtime_defaults_1.default)(config, options);
14
15
  config = (0, with_expo_notifications_1.default)(config, options);
15
16
  config = (0, with_firebase_messaging_manifest_1.default)(config, options);
17
+ config = (0, with_firebase_messaging_registration_1.default)(config, options);
16
18
  config = (0, with_rnfirebase_disable_spm_1.default)(config);
17
19
  return config;
18
20
  };
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_plugins_1 = require("expo/config-plugins");
4
4
  const FCM_DEFAULT_CHANNEL = 'com.google.firebase.messaging.default_notification_channel_id';
5
5
  const FCM_DEFAULT_COLOR = 'com.google.firebase.messaging.default_notification_color';
6
+ const FCM_INSTALLATION_ID_ENABLED = 'firebase_messaging_installation_id_enabled';
7
+ const RN_FIREBASE_MESSAGING_SERVICE = 'io.invertase.firebase.messaging.ReactNativeFirebaseMessagingService';
8
+ const BUBBLES_FIREBASE_MESSAGING_SERVICE = '.BubblesFirebaseMessagingService';
9
+ const BUBBLES_FIREBASE_MESSAGING_REGISTRAR = '.BubblesFirebaseMessagingRegistrar';
6
10
  const withFirebaseMessagingManifest = (config, options) => {
7
11
  return (0, config_plugins_1.withAndroidManifest)(config, config => {
8
12
  const manifest = config.modResults;
@@ -17,6 +21,8 @@ const withFirebaseMessagingManifest = (config, options) => {
17
21
  if (channel) {
18
22
  setToolsReplace(channel.$, 'android:value');
19
23
  }
24
+ config_plugins_1.AndroidConfig.Manifest.addMetaDataItemToMainApplication(application, FCM_INSTALLATION_ID_ENABLED, 'true', 'value');
25
+ addBubblesFirebaseMessagingRegistrationEntries(application, getAndroidPackageName(config));
20
26
  // Expo only creates the FCM color metadata when a notification
21
27
  // color has actually been configured.
22
28
  if (options.androidNotificationColor) {
@@ -29,6 +35,36 @@ const withFirebaseMessagingManifest = (config, options) => {
29
35
  return config;
30
36
  });
31
37
  };
38
+ function getAndroidPackageName(config) {
39
+ const packageName = config.android?.package?.trim();
40
+ if (!packageName) {
41
+ throw new Error('[@fishonfire/bubbles-expo] "expo.android.package" is required to configure Android Firebase Messaging registration.');
42
+ }
43
+ return packageName;
44
+ }
45
+ function addBubblesFirebaseMessagingRegistrationEntries(application, packageName) {
46
+ application.service = application.service ?? [];
47
+ application.provider = application.provider ?? [];
48
+ removeManifestService(application, RN_FIREBASE_MESSAGING_SERVICE);
49
+ removeManifestService(application, BUBBLES_FIREBASE_MESSAGING_SERVICE);
50
+ upsertManifestProvider(application, {
51
+ $: {
52
+ 'android:name': BUBBLES_FIREBASE_MESSAGING_REGISTRAR,
53
+ 'android:authorities': `${packageName}.bubblesnotifications.fcmregistrar`,
54
+ 'android:exported': 'false',
55
+ 'android:initOrder': '100',
56
+ },
57
+ });
58
+ }
59
+ function removeManifestService(application, serviceName) {
60
+ application.service = (application.service ?? []).filter(item => item.$['android:name'] !== serviceName);
61
+ }
62
+ function upsertManifestProvider(application, provider) {
63
+ application.provider = [
64
+ ...(application.provider ?? []).filter(item => item.$['android:name'] !== provider.$['android:name']),
65
+ provider,
66
+ ];
67
+ }
32
68
  function setToolsReplace(attributes, value) {
33
69
  attributes['tools:replace'] = value;
34
70
  }
@@ -0,0 +1,4 @@
1
+ import { ConfigPlugin } from 'expo/config-plugins';
2
+ import type { NormalizedBubblesNotificationsExpoPluginConfig } from './config';
3
+ declare const withFirebaseMessagingRegistration: ConfigPlugin<NormalizedBubblesNotificationsExpoPluginConfig>;
4
+ export default withFirebaseMessagingRegistration;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const promises_1 = __importDefault(require("node:fs/promises"));
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const config_plugins_1 = require("expo/config-plugins");
9
+ const REGISTRAR_CLASS = 'BubblesFirebaseMessagingRegistrar';
10
+ const withFirebaseMessagingRegistration = config => {
11
+ return (0, config_plugins_1.withDangerousMod)(config, [
12
+ 'android',
13
+ async (config) => {
14
+ const packageName = getAndroidPackageName(config);
15
+ const sourceDirectory = node_path_1.default.join(config.modRequest.projectRoot, 'android', 'app', 'src', 'main', 'java', ...packageName.split('.'));
16
+ await promises_1.default.mkdir(sourceDirectory, { recursive: true });
17
+ await promises_1.default.writeFile(node_path_1.default.join(sourceDirectory, `${REGISTRAR_CLASS}.java`), buildFirebaseMessagingRegistrarSource(packageName));
18
+ return config;
19
+ },
20
+ ]);
21
+ };
22
+ function getAndroidPackageName(config) {
23
+ const packageName = config.android?.package?.trim();
24
+ if (!packageName) {
25
+ throw new Error('[@fishonfire/bubbles-expo] "expo.android.package" is required to configure Android Firebase Messaging registration.');
26
+ }
27
+ return packageName;
28
+ }
29
+ function buildFirebaseMessagingRegistrarSource(packageName) {
30
+ return `package ${packageName};
31
+
32
+ import android.content.ContentProvider;
33
+ import android.content.ContentValues;
34
+ import android.database.Cursor;
35
+ import android.net.Uri;
36
+ import android.util.Log;
37
+
38
+ import androidx.annotation.NonNull;
39
+ import androidx.annotation.Nullable;
40
+
41
+ public final class ${REGISTRAR_CLASS} extends ContentProvider {
42
+ private static final String TAG = "BubblesFCMRegistrar";
43
+
44
+ @Override
45
+ public boolean onCreate() {
46
+ try {
47
+ Class<?> firebaseAppClass = Class.forName("com.google.firebase.FirebaseApp");
48
+ Class<?> firebaseMessagingClass = Class.forName("com.google.firebase.messaging.FirebaseMessaging");
49
+
50
+ if (getContext() != null) {
51
+ Object apps = firebaseAppClass
52
+ .getMethod("getApps", android.content.Context.class)
53
+ .invoke(null, getContext());
54
+
55
+ if (apps instanceof java.util.List && ((java.util.List<?>) apps).isEmpty()) {
56
+ firebaseAppClass
57
+ .getMethod("initializeApp", android.content.Context.class)
58
+ .invoke(null, getContext());
59
+ }
60
+ }
61
+
62
+ Object messaging = firebaseMessagingClass
63
+ .getMethod("getInstance")
64
+ .invoke(null);
65
+
66
+ firebaseMessagingClass
67
+ .getMethod("register")
68
+ .invoke(messaging);
69
+ } catch (ReflectiveOperationException | RuntimeException error) {
70
+ Log.w(TAG, "Failed to start Firebase Messaging registration.", error);
71
+ }
72
+
73
+ return false;
74
+ }
75
+
76
+ @Nullable
77
+ @Override
78
+ public Cursor query(
79
+ @NonNull Uri uri,
80
+ @Nullable String[] projection,
81
+ @Nullable String selection,
82
+ @Nullable String[] selectionArgs,
83
+ @Nullable String sortOrder) {
84
+ return null;
85
+ }
86
+
87
+ @Nullable
88
+ @Override
89
+ public String getType(@NonNull Uri uri) {
90
+ return null;
91
+ }
92
+
93
+ @Nullable
94
+ @Override
95
+ public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
96
+ return null;
97
+ }
98
+
99
+ @Override
100
+ public int delete(
101
+ @NonNull Uri uri,
102
+ @Nullable String selection,
103
+ @Nullable String[] selectionArgs) {
104
+ return 0;
105
+ }
106
+
107
+ @Override
108
+ public int update(
109
+ @NonNull Uri uri,
110
+ @Nullable ContentValues values,
111
+ @Nullable String selection,
112
+ @Nullable String[] selectionArgs) {
113
+ return 0;
114
+ }
115
+ }
116
+ `;
117
+ }
118
+ exports.default = withFirebaseMessagingRegistration;