diff --git a/.spellcheck.dict.txt b/.spellcheck.dict.txt
index 74087c8078..d7d2f40149 100644
--- a/.spellcheck.dict.txt
+++ b/.spellcheck.dict.txt
@@ -55,6 +55,7 @@ Fastlane
FCM
firebase
Firebase
+FirebaseApp
firebase-ios-sdk
Firestore
getIdToken
diff --git a/docs/app/usage.md b/docs/app/usage.md
index 3cd0265396..e304c8b5e2 100644
--- a/docs/app/usage.md
+++ b/docs/app/usage.md
@@ -21,13 +21,14 @@ for manually initializing secondary Firebase app instances.
Currently, the native Firebase SDKs only provide functionality for creating secondary apps on the following services:
-- [AppCheck](/app-check/usage).
+- [App Check](/app-check/usage).
- [Authentication](/auth/usage).
- [Realtime Database](/database/usage).
- [Cloud Firestore](/firestore/usage).
- [Cloud Functions](/functions/usage)
- [Cloud Storage](/storage/usage).
- [ML](/ml/usage).
+- [Installations](/installations/usage),
- [Remote Config](/remote-config/usage).
## Initializing secondary apps
diff --git a/docs/in-app-messaging/usage/index.md b/docs/in-app-messaging/usage/index.md
index 72358725d4..04ad034e8a 100644
--- a/docs/in-app-messaging/usage/index.md
+++ b/docs/in-app-messaging/usage/index.md
@@ -2,7 +2,7 @@
title: In App Messaging
description: Installation and getting started with In App Messaging.
icon: //static.invertase.io/assets/firebase/in-app-messaging.svg
-next: /ml/usage
+next: /installations/usage
previous: /dynamic-links/usage
---
diff --git a/docs/installations/usage/index.md b/docs/installations/usage/index.md
new file mode 100644
index 0000000000..ed98d490ac
--- /dev/null
+++ b/docs/installations/usage/index.md
@@ -0,0 +1,37 @@
+---
+title: Installations
+description: Installation and getting started with Installations.
+icon: //static.invertase.io/assets/social/firebase-logo.png
+next: /ml/usage
+previous: /in-app-messaging/usage
+---
+
+# Installation
+
+This module requires that the `@react-native-firebase/app` module is already setup and installed. To install the "app"
+module, view the [Getting Started](/) documentation.
+
+```bash
+# Install & setup the app module
+yarn add @react-native-firebase/app
+
+# Install the installations module
+yarn add @react-native-firebase/installations
+
+# If you're developing your app using iOS, run this command
+cd ios/ && pod install
+```
+
+# What does it do
+
+The Firebase installations service:
+
+- provides a unique identifier for a Firebase installation
+- provides an auth token for a Firebase installation
+- provides an API to perform GDPR-compliant deletion of a Firebase installation.
+
+Each configured `FirebaseApp` has a corresponding single instance of Installations. An instance of the class provides access to the installation info for the FirebaseApp as well as the ability to delete it. A Firebase Installation is unique by `FirebaseApp.name` and `FirebaseApp.options.googleAppID`
+
+# Usage
+
+Please see the API Reference for detailed usage information on the available APIs
diff --git a/docs/ml/usage/index.md b/docs/ml/usage/index.md
index 8bb49c671b..3c48815c14 100644
--- a/docs/ml/usage/index.md
+++ b/docs/ml/usage/index.md
@@ -3,7 +3,7 @@ title: ML
description: Installation and getting started with ML.
icon: //static.invertase.io/assets/firebase/ml-kit.svg
next: /remote-config/usage
-previous: /in-app-messaging/usage
+previous: /installations/usage
---
# Installation
diff --git a/docs/sidebar.yaml b/docs/sidebar.yaml
index 51897590ca..86dd79753a 100644
--- a/docs/sidebar.yaml
+++ b/docs/sidebar.yaml
@@ -97,6 +97,10 @@
- - - Usage
- '/in-app-messaging/usage'
- '//static.invertase.io/assets/firebase/in-app-messaging.svg'
+- - Installations
+ - - - Usage
+ - '/installations/usage'
+ - '//static.invertase.io/assets/social/firebase-logo.png'
- - ML
- - - Usage
- '/ml/usage'
diff --git a/packages/app/lib/internal/constants.js b/packages/app/lib/internal/constants.js
index 4bc585ef6b..aae6cb3d62 100644
--- a/packages/app/lib/internal/constants.js
+++ b/packages/app/lib/internal/constants.js
@@ -27,6 +27,7 @@ export const KNOWN_NAMESPACES = [
'crashlytics',
'database',
'inAppMessaging',
+ 'installations',
'firestore',
'functions',
'indexing',
diff --git a/packages/installations/.npmignore b/packages/installations/.npmignore
new file mode 100644
index 0000000000..d9fa30e5a5
--- /dev/null
+++ b/packages/installations/.npmignore
@@ -0,0 +1,65 @@
+# Built application files
+android/*/build/
+
+# Crashlytics configuations
+android/com_crashlytics_export_strings.xml
+
+# Local configuration file (sdk path, etc)
+android/local.properties
+
+# Gradle generated files
+android/.gradle/
+
+# Signing files
+android/.signing/
+
+# User-specific configurations
+android/.idea/gradle.xml
+android/.idea/libraries/
+android/.idea/workspace.xml
+android/.idea/tasks.xml
+android/.idea/.name
+android/.idea/compiler.xml
+android/.idea/copyright/profiles_settings.xml
+android/.idea/encodings.xml
+android/.idea/misc.xml
+android/.idea/modules.xml
+android/.idea/scopes/scope_settings.xml
+android/.idea/vcs.xml
+android/*.iml
+
+# Xcode
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+*.xcuserstate
+ios/Pods
+ios/build
+*project.xcworkspace*
+*xcuserdata*
+
+# OS-specific files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.dbandroid/gradle
+android/gradlew
+android/build
+android/gradlew.bat
+android/gradle/
+
+.idea
+coverage
+yarn.lock
+e2e/
+.github
+.vscode
+.nyc_output
+android/.settings
+*.coverage.json
+.circleci
+.eslintignore
diff --git a/packages/installations/LICENSE b/packages/installations/LICENSE
new file mode 100644
index 0000000000..ef3ed44f06
--- /dev/null
+++ b/packages/installations/LICENSE
@@ -0,0 +1,32 @@
+Apache-2.0 License
+------------------
+
+Copyright (c) 2016-present Invertase Limited & Contributors
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this library except in compliance with the License.
+
+You may obtain a copy of the Apache-2.0 License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+Creative Commons Attribution 3.0 License
+----------------------------------------
+
+Copyright (c) 2016-present Invertase Limited & Contributors
+
+Documentation and other instructional materials provided for this project
+(including on a separate documentation repository or it's documentation website) are
+licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks
+contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above.
+
+You may obtain a copy of the Creative Commons Attribution 3.0 License at
+
+ https://creativecommons.org/licenses/by/3.0/
diff --git a/packages/installations/README.md b/packages/installations/README.md
new file mode 100644
index 0000000000..b926f3ac08
--- /dev/null
+++ b/packages/installations/README.md
@@ -0,0 +1,61 @@
+
+
+
+
+
React Native Firebase - Installations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+----
+
+Entry point for Firebase installations.
+
+The Firebase installations service:
+
+- provides a unique identifier for a Firebase installation
+- provides an auth token for a Firebase installation
+- provides a API to perform GDPR-compliant deletion of a Firebase installation.
+
+
+[> Learn More](https://firebase.google.com/docs/projects/manage-installations)
+
+## Installation
+
+Requires `@react-native-firebase/app` to be installed.
+
+```bash
+yarn add @react-native-firebase/installations
+```
+
+## Documentation
+
+ - [Guides](https://rnfirebase.io/installations/usage/)
+ - [Reference](https://rnfirebase.io/reference/installations)
+
+## License
+
+- See [LICENSE](/LICENSE)
+
+----
+
+
+
+
+ Built and maintained with đź’› by Invertase.
+
+
+
+----
diff --git a/packages/installations/RNFBInstallations.podspec b/packages/installations/RNFBInstallations.podspec
new file mode 100644
index 0000000000..3a9aa1b4cd
--- /dev/null
+++ b/packages/installations/RNFBInstallations.podspec
@@ -0,0 +1,45 @@
+require 'json'
+package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
+appPackage = JSON.parse(File.read(File.join('..', 'app', 'package.json')))
+
+coreVersionDetected = appPackage['version']
+coreVersionRequired = package['peerDependencies'][appPackage['name']]
+firebase_sdk_version = appPackage['sdkVersions']['ios']['firebase']
+if coreVersionDetected != coreVersionRequired
+ Pod::UI.warn "NPM package '#{package['name']}' depends on '#{appPackage['name']}' v#{coreVersionRequired} but found v#{coreVersionDetected}, this might cause build issues or runtime crashes."
+end
+
+Pod::Spec.new do |s|
+ s.name = "RNFBInstallations"
+ s.version = package["version"]
+ s.description = package["description"]
+ s.summary = <<-DESC
+ A well tested feature rich Firebase implementation for React Native, supporting iOS & Android.
+ DESC
+ s.homepage = "http://invertase.io/oss/react-native-firebase"
+ s.license = package['license']
+ s.authors = "Invertase Limited"
+ s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" }
+ s.social_media_url = 'http://twitter.com/invertaseio'
+ s.ios.deployment_target = "10.0"
+ s.source_files = 'ios/**/*.{h,m}'
+
+ # React Native dependencies
+ s.dependency 'React-Core'
+ s.dependency 'RNFBApp'
+
+ if defined?($FirebaseSDKVersion)
+ Pod::UI.puts "#{s.name}: Using user specified Firebase SDK version '#{$FirebaseSDKVersion}'"
+ firebase_sdk_version = $FirebaseSDKVersion
+ end
+
+ # Firebase dependencies
+ s.dependency 'Firebase/Installations', firebase_sdk_version
+
+ if defined?($RNFirebaseAsStaticFramework)
+ Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNFirebaseAsStaticFramework}'"
+ s.static_framework = $RNFirebaseAsStaticFramework
+ else
+ s.static_framework = false
+ end
+end
diff --git a/packages/installations/__tests__/installations.test.ts b/packages/installations/__tests__/installations.test.ts
new file mode 100644
index 0000000000..c1a945bcad
--- /dev/null
+++ b/packages/installations/__tests__/installations.test.ts
@@ -0,0 +1,21 @@
+import { firebase } from '../lib';
+
+describe('installations()', function () {
+ describe('namespace', function () {
+ it('accessible from firebase.app()', function () {
+ const app = firebase.app();
+ expect(app.installations).toBeDefined();
+ expect(app.installations().app).toEqual(app);
+ });
+
+ it('supports multiple apps', async function () {
+ expect(firebase.installations().app.name).toEqual('[DEFAULT]');
+ expect(firebase.installations(firebase.app('secondaryFromNative')).app.name).toEqual(
+ 'secondaryFromNative',
+ );
+ expect(firebase.app('secondaryFromNative').installations().app.name).toEqual(
+ 'secondaryFromNative',
+ );
+ });
+ });
+});
diff --git a/packages/installations/android/.editorconfig b/packages/installations/android/.editorconfig
new file mode 100644
index 0000000000..670398e990
--- /dev/null
+++ b/packages/installations/android/.editorconfig
@@ -0,0 +1,10 @@
+# editorconfig
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/packages/installations/android/build.gradle b/packages/installations/android/build.gradle
new file mode 100644
index 0000000000..75788c2138
--- /dev/null
+++ b/packages/installations/android/build.gradle
@@ -0,0 +1,99 @@
+import io.invertase.gradle.common.PackageJson
+
+buildscript {
+ // The Android Gradle plugin is only required when opening the android folder stand-alone.
+ // This avoids unnecessary downloads and potential conflicts when the library is included as a
+ // module dependency in an application project.
+ if (project == rootProject) {
+ repositories {
+ google()
+ mavenCentral()
+ }
+
+ dependencies {
+ classpath("com.android.tools.build:gradle:7.0.0")
+ }
+ }
+}
+
+plugins {
+ id "io.invertase.gradle.build" version "1.5"
+}
+
+def appProject
+if (findProject(':@react-native-firebase_app')) {
+ appProject = project(':@react-native-firebase_app')
+} else if (findProject(':react-native-firebase_app')) {
+ appProject = project(':react-native-firebase_app')
+} else {
+ throw new GradleException('Could not find the react-native-firebase/app package, have you installed it?')
+}
+def packageJson = PackageJson.getForProject(project)
+def appPackageJson = PackageJson.getForProject(appProject)
+def firebaseBomVersion = appPackageJson['sdkVersions']['android']['firebase']
+def jsonMinSdk = appPackageJson['sdkVersions']['android']['minSdk']
+def jsonTargetSdk = appPackageJson['sdkVersions']['android']['targetSdk']
+def jsonCompileSdk = appPackageJson['sdkVersions']['android']['compileSdk']
+def jsonBuildTools = appPackageJson['sdkVersions']['android']['buildTools']
+def coreVersionDetected = appPackageJson['version']
+def coreVersionRequired = packageJson['peerDependencies'][appPackageJson['name']]
+// Only log after build completed so log warning appears at the end
+if (coreVersionDetected != coreVersionRequired) {
+ gradle.buildFinished {
+ project.logger.warn("ReactNativeFirebase WARNING: NPM package '${packageJson['name']}' depends on '${appPackageJson['name']}' v${coreVersionRequired} but found v${coreVersionDetected}, this might cause build issues or runtime crashes.")
+ }
+}
+
+project.ext {
+ set('react-native', [
+ versions: [
+ android : [
+ minSdk : jsonMinSdk,
+ targetSdk : jsonTargetSdk,
+ compileSdk: jsonCompileSdk,
+ // optional as gradle.buildTools comes with one by default
+ // overriding here though to match the version RN uses
+ buildTools: jsonBuildTools
+ ],
+
+ firebase: [
+ bom: firebaseBomVersion,
+ ],
+ ],
+ ])
+}
+
+android {
+ defaultConfig {
+ multiDexEnabled true
+ }
+ lintOptions {
+ disable 'GradleCompatible'
+ abortOnError false
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+ sourceSets {
+ main {
+ java.srcDirs = ['src/main/java', 'src/reactnative/java']
+ }
+ }
+}
+
+repositories {
+ google()
+ mavenCentral()
+}
+
+dependencies {
+ api appProject
+ implementation platform("com.google.firebase:firebase-bom:${ReactNative.ext.getVersion("firebase", "bom")}")
+ implementation "com.google.firebase:firebase-installations"
+}
+
+ReactNative.shared.applyPackageVersion()
+ReactNative.shared.applyDefaultExcludes()
+ReactNative.module.applyAndroidVersions()
+ReactNative.module.applyReactNativeDependency("api")
diff --git a/packages/installations/android/lint.xml b/packages/installations/android/lint.xml
new file mode 100644
index 0000000000..c3dd72aca0
--- /dev/null
+++ b/packages/installations/android/lint.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/packages/installations/android/settings.gradle b/packages/installations/android/settings.gradle
new file mode 100644
index 0000000000..82e62bda0e
--- /dev/null
+++ b/packages/installations/android/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = '@react-native-firebase_installations'
diff --git a/packages/installations/android/src/main/AndroidManifest.xml b/packages/installations/android/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..7790b94d21
--- /dev/null
+++ b/packages/installations/android/src/main/AndroidManifest.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsModule.java b/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsModule.java
new file mode 100644
index 0000000000..eb40ad7a97
--- /dev/null
+++ b/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsModule.java
@@ -0,0 +1,107 @@
+package io.invertase.firebase.installations;
+
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import android.util.Log;
+import com.facebook.react.bridge.*;
+import com.google.android.gms.tasks.Tasks;
+import com.google.firebase.FirebaseApp;
+import com.google.firebase.installations.FirebaseInstallations;
+import io.invertase.firebase.common.ReactNativeFirebaseModule;
+
+public class ReactNativeFirebaseInstallationsModule extends ReactNativeFirebaseModule {
+ private static final String TAG = "Installations";
+
+ ReactNativeFirebaseInstallationsModule(ReactApplicationContext reactContext) {
+ super(reactContext, TAG);
+ }
+
+ @ReactMethod
+ public void getId(String appName, Promise promise) {
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
+
+ Tasks.call(
+ getExecutor(),
+ () -> {
+ return Tasks.await(FirebaseInstallations.getInstance(firebaseApp).getId());
+ })
+ .addOnCompleteListener(
+ getExecutor(),
+ (task) -> {
+ if (task.isSuccessful()) {
+ promise.resolve(task.getResult());
+ } else {
+ Log.e(
+ TAG,
+ "RNFB: Unknown error while fetching Installations ID "
+ + task.getException().getMessage());
+ rejectPromiseWithCodeAndMessage(
+ promise, "id-error", task.getException().getMessage());
+ }
+ });
+ }
+
+ @ReactMethod
+ public void getToken(String appName, boolean forceRefresh, Promise promise) {
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
+ Tasks.call(
+ getExecutor(),
+ () -> {
+ return Tasks.await(
+ FirebaseInstallations.getInstance(firebaseApp).getToken(forceRefresh));
+ })
+ .addOnCompleteListener(
+ getExecutor(),
+ (task) -> {
+ if (task.isSuccessful()) {
+ promise.resolve(task.getResult().getToken());
+ } else {
+ Log.e(
+ TAG,
+ "RNFB: Unknown error while fetching Installations token "
+ + task.getException().getMessage());
+ rejectPromiseWithCodeAndMessage(
+ promise, "token-error", task.getException().getMessage());
+ }
+ });
+ }
+
+ @ReactMethod
+ public void delete(String appName, Promise promise) {
+ FirebaseApp firebaseApp = FirebaseApp.getInstance(appName);
+ Tasks.call(
+ getExecutor(),
+ () -> {
+ return Tasks.await(FirebaseInstallations.getInstance(firebaseApp).delete());
+ })
+ .addOnCompleteListener(
+ getExecutor(),
+ (task) -> {
+ if (task.isSuccessful()) {
+ promise.resolve(null);
+ } else {
+ Log.e(
+ TAG,
+ "RNFB: Unknown error while deleting Installations"
+ + task.getException().getMessage());
+ rejectPromiseWithCodeAndMessage(
+ promise, "delete-error", task.getException().getMessage());
+ }
+ });
+ }
+}
diff --git a/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsPackage.java b/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsPackage.java
new file mode 100644
index 0000000000..a845533203
--- /dev/null
+++ b/packages/installations/android/src/main/java/io/invertase/firebase/installations/ReactNativeFirebaseInstallationsPackage.java
@@ -0,0 +1,41 @@
+package io.invertase.firebase.installations;
+
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import com.facebook.react.ReactPackage;
+import com.facebook.react.bridge.NativeModule;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.uimanager.ViewManager;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class ReactNativeFirebaseInstallationsPackage implements ReactPackage {
+ @Override
+ public List createNativeModules(ReactApplicationContext reactContext) {
+ List modules = new ArrayList<>();
+ modules.add(new ReactNativeFirebaseInstallationsModule(reactContext));
+ return modules;
+ }
+
+ @Override
+ public List createViewManagers(ReactApplicationContext reactContext) {
+ return Collections.emptyList();
+ }
+}
diff --git a/packages/installations/e2e/installations.e2e.js b/packages/installations/e2e/installations.e2e.js
new file mode 100644
index 0000000000..41967e0ebd
--- /dev/null
+++ b/packages/installations/e2e/installations.e2e.js
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+const jwt = require('jsonwebtoken');
+
+const ID_LENGTH = 22;
+const PROJECT_ID = 448618578101; // this is "magic", it's the react-native-firebase-testing project ID
+
+describe('installations()', function () {
+ describe('getId()', function () {
+ it('returns a valid installation id', async function () {
+ const id = await firebase.installations().getId();
+ id.should.be.a.String();
+ id.length.should.be.equals(ID_LENGTH);
+ });
+ });
+
+ describe('getToken()', function () {
+ it('returns a valid auth token with no arguments', async function () {
+ const id = await firebase.installations().getId();
+ const token = await firebase.installations().getToken();
+ token.should.be.a.String();
+ token.should.not.equal('');
+ const decodedToken = jwt.decode(token);
+ decodedToken.fid.should.equal(id); // fid == firebase installations id
+ decodedToken.projectNumber.should.equal(PROJECT_ID);
+ if (decodedToken.exp < Date.now()) {
+ Promise.reject('Token already expired');
+ }
+
+ const token2 = await firebase.installations().getToken(true);
+ token2.should.be.a.String();
+ token2.should.not.equal('');
+ const decodedToken2 = jwt.decode(token2);
+ decodedToken2.fid.should.equal(id);
+ decodedToken2.projectNumber.should.equal(PROJECT_ID);
+ if (decodedToken2.exp < Date.now()) {
+ Promise.reject('Token already expired');
+ }
+ (token === token2).should.be.false();
+ });
+ });
+
+ describe('delete()', function () {
+ it('successfully deletes', async function () {
+ const id = await firebase.installations().getId();
+ id.should.be.a.String();
+ id.length.should.be.equals(ID_LENGTH);
+ await firebase.installations().delete();
+
+ // New id should be different
+ const id2 = await firebase.installations().getId();
+ id2.should.be.a.String();
+ id2.length.should.be.equals(ID_LENGTH);
+ (id === id2).should.be.false();
+
+ const token = await firebase.installations().getToken(false);
+ const decodedToken = jwt.decode(token);
+ decodedToken.fid.should.equal(id2); // fid == firebase installations id
+ decodedToken.projectNumber.should.equal(PROJECT_ID);
+ if (decodedToken.exp < Date.now()) {
+ Promise.reject('Token already expired');
+ }
+ });
+ });
+});
diff --git a/packages/installations/ios/RNFBInstallations.xcodeproj/project.pbxproj b/packages/installations/ios/RNFBInstallations.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..d238d5a79d
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations.xcodeproj/project.pbxproj
@@ -0,0 +1,349 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 48;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 2744B98621F45429004F8E3F /* RNFBInstallationsModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 2744B98521F45429004F8E3F /* RNFBInstallationsModule.m */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 2744B98021F45429004F8E3F /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 16;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 2744B98221F45429004F8E3F /* libRNFBInstallations.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFBInstallations.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2744B98421F45429004F8E3F /* RNFBInstallationsModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = RNFBInstallationsModule.h; path = RNFBInstallations/RNFBInstallationsModule.h; sourceTree = SOURCE_ROOT; };
+ 2744B98521F45429004F8E3F /* RNFBInstallationsModule.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = RNFBInstallationsModule.m; path = RNFBInstallations/RNFBInstallationsModule.m; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 2744B97F21F45429004F8E3F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 2744B97521F452B8004F8E3F /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 2744B98221F45429004F8E3F /* libRNFBInstallations.a */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 2744B98321F45429004F8E3F /* RNFBInstallations */ = {
+ isa = PBXGroup;
+ children = (
+ 2744B9A121F48736004F8E3F /* converters */,
+ 2744B98C21F45C64004F8E3F /* common */,
+ 2744B98421F45429004F8E3F /* RNFBInstallationsModule.h */,
+ 2744B98521F45429004F8E3F /* RNFBInstallationsModule.m */,
+ );
+ path = RNFBInstallations;
+ sourceTree = "";
+ };
+ 3323F52AAFE26B7384BE4DE3 = {
+ isa = PBXGroup;
+ children = (
+ 2744B98321F45429004F8E3F /* RNFBInstallations */,
+ 2744B97521F452B8004F8E3F /* Products */,
+ );
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 2744B98121F45429004F8E3F /* RNFBInstallations */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBInstallations" */;
+ buildPhases = (
+ 2744B97E21F45429004F8E3F /* Sources */,
+ 2744B97F21F45429004F8E3F /* Frameworks */,
+ 2744B98021F45429004F8E3F /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = RNFBInstallations;
+ productName = RNFBInstallations;
+ productReference = 2744B98221F45429004F8E3F /* libRNFBInstallations.a */;
+ productType = "com.apple.product-type.library.static";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 3323F95273A95DB34F55C6D7 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ CLASSPREFIX = RNFBInstallations;
+ LastUpgradeCheck = 1010;
+ ORGANIZATIONNAME = Invertase;
+ TargetAttributes = {
+ 2744B98121F45429004F8E3F = {
+ CreatedOnToolsVersion = 10.1;
+ ProvisioningStyle = Automatic;
+ };
+ };
+ };
+ buildConfigurationList = 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBInstallations" */;
+ compatibilityVersion = "Xcode 8.0";
+ developmentRegion = English;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ );
+ mainGroup = 3323F52AAFE26B7384BE4DE3;
+ productRefGroup = 2744B97521F452B8004F8E3F /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 2744B98121F45429004F8E3F /* RNFBInstallations */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2744B97E21F45429004F8E3F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2744B98621F45429004F8E3F /* RNFBInstallationsModule.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+ 2744B98921F45429004F8E3F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 2744B98A21F45429004F8E3F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CODE_SIGN_IDENTITY = "iPhone Developer";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ OTHER_LDFLAGS = "-ObjC";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = iphoneos;
+ SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 3323F77D701E1896E6D239CF /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "${BUILT_PRODUCTS_DIR}/**",
+ "${SRCROOT}/../../../ios/Firebase/**",
+ "$(FIREBASE_SEARCH_PATH)/Firebase/**",
+ "$(SRCROOT)/../../../ios/Pods/FirebaseInstallations/Frameworks",
+ "$(SRCROOT)/../../../tests/ios/Pods/FirebaseInstallations/Frameworks",
+ );
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(REACT_SEARCH_PATH)/React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ "$(SRCROOT)/../../react-native-firebase/ios/**",
+ "$(FIREBASE_SEARCH_PATH)/Firebase/**",
+ "${SRCROOT}/../../../ios/Firebase/**",
+ "${SRCROOT}/../../../ios/Pods/Headers/Public/**",
+ "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**",
+ "$(SRCROOT)/../../../node_modules/react-native/React/**",
+ "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**",
+ "$(SRCROOT)/../../../packages/app/ios/**",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACH_O_TYPE = staticlib;
+ OTHER_LDFLAGS = "$(inherited)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ };
+ name = Release;
+ };
+ 3323F7E33E1559A2B9826720 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ "${BUILT_PRODUCTS_DIR}/**",
+ "${SRCROOT}/../../../ios/Firebase/**",
+ "$(FIREBASE_SEARCH_PATH)/Firebase/**",
+ "$(SRCROOT)/../../../ios/Pods/FirebaseInstallations/Frameworks",
+ );
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = (
+ "$(inherited)",
+ "$(REACT_SEARCH_PATH)/React/**",
+ "$(SRCROOT)/../../react-native/React/**",
+ "$(SRCROOT)/../../react-native-firebase/ios/**",
+ "$(FIREBASE_SEARCH_PATH)/Firebase/**",
+ "${SRCROOT}/../../../ios/Firebase/**",
+ "${SRCROOT}/../../../ios/Pods/Headers/Public/**",
+ "${SRCROOT}/../../../tests/ios/Pods/Headers/Public/**",
+ "$(SRCROOT)/../../../node_modules/react-native/React/**",
+ "$(SRCROOT)/../../../node_modules/react-native-firebase/ios/**",
+ "$(SRCROOT)/../../../packages/app/ios/**",
+ );
+ IPHONEOS_DEPLOYMENT_TARGET = 10.0;
+ LIBRARY_SEARCH_PATHS = "$(inherited)";
+ MACH_O_TYPE = staticlib;
+ ONLY_ACTIVE_ARCH = YES;
+ OTHER_LDFLAGS = "$(inherited)";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ };
+ name = Debug;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 2744B98821F45429004F8E3F /* Build configuration list for PBXNativeTarget "RNFBInstallations" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 2744B98921F45429004F8E3F /* Debug */,
+ 2744B98A21F45429004F8E3F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 3323F1C5716BA966BBBB95A4 /* Build configuration list for PBXProject "RNFBInstallations" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 3323F7E33E1559A2B9826720 /* Debug */,
+ 3323F77D701E1896E6D239CF /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 3323F95273A95DB34F55C6D7 /* Project object */;
+}
diff --git a/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000000..919434a625
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000000..18d981003d
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000000..0c67376eba
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/packages/installations/ios/RNFBInstallations.xcodeproj/xcshareddata/IDETemplateMacros.plist b/packages/installations/ios/RNFBInstallations.xcodeproj/xcshareddata/IDETemplateMacros.plist
new file mode 100644
index 0000000000..63f0a6e5dd
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations.xcodeproj/xcshareddata/IDETemplateMacros.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ FILEHEADER
+
+/**
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
diff --git a/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.h b/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.h
new file mode 100644
index 0000000000..a734bb8f29
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.h
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import
+
+#import
+
+@interface RNFBInstallationsModule : NSObject
+
+@end
diff --git a/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.m b/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.m
new file mode 100644
index 0000000000..7b07b36a0b
--- /dev/null
+++ b/packages/installations/ios/RNFBInstallations/RNFBInstallationsModule.m
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import
+#import
+
+#import "RNFBApp/RNFBSharedUtils.h"
+#import "RNFBInstallationsModule.h"
+
+#import "FirebaseInstallations/FIRInstallations.h"
+
+@implementation RNFBInstallationsModule
+#pragma mark -
+#pragma mark Module Setup
+
+RCT_EXPORT_MODULE();
+
+- (dispatch_queue_t)methodQueue {
+ return dispatch_get_main_queue();
+}
+
+#pragma mark -
+#pragma mark Firebase Installations Methods
+
+RCT_EXPORT_METHOD(delete
+ : (FIRApp *)firebaseApp
+ : (RCTPromiseResolveBlock)resolve
+ : (RCTPromiseRejectBlock)reject) {
+ FIRInstallations *installations = [FIRInstallations installationsWithApp:firebaseApp];
+ [installations deleteWithCompletion:^(NSError *_Nullable error) {
+ if (error != nil) {
+ // Handle any errors if the delete failed
+ DLog(@"Unable to delete Installations ID: %@", error);
+ [RNFBSharedUtils rejectPromiseWithUserInfo:reject
+ userInfo:(NSMutableDictionary *)@{
+ @"code" : @"delete-error",
+ @"message" : [error localizedDescription],
+ }];
+ return;
+ }
+
+ resolve([NSNull null]);
+ }];
+}
+
+RCT_EXPORT_METHOD(getId
+ : (FIRApp *)firebaseApp
+ : (RCTPromiseResolveBlock)resolve
+ : (RCTPromiseRejectBlock)reject) {
+ FIRInstallations *installations = [FIRInstallations installationsWithApp:firebaseApp];
+ [installations installationIDWithCompletion:^(NSString *_Nullable id, NSError *_Nullable error) {
+ if (error != nil) {
+ // Handle any errors if the id was not retrieved.
+ DLog(@"Unable to retrieve Installations ID: %@", error);
+ [RNFBSharedUtils rejectPromiseWithUserInfo:reject
+ userInfo:(NSMutableDictionary *)@{
+ @"code" : @"id-error",
+ @"message" : [error localizedDescription],
+ }];
+ return;
+ }
+ if (id == nil) {
+ DLog(@"Unable to retrieve Installations ID.");
+ [RNFBSharedUtils rejectPromiseWithUserInfo:reject
+ userInfo:(NSMutableDictionary *)@{
+ @"code" : @"id-null",
+ @"message" : @"no id fetched",
+ }];
+ return;
+ }
+
+ resolve(id);
+ }];
+}
+
+RCT_EXPORT_METHOD(getToken
+ : (FIRApp *)firebaseApp
+ : (BOOL)forceRefresh
+ : (RCTPromiseResolveBlock)resolve
+ : (RCTPromiseRejectBlock)reject) {
+ FIRInstallations *installations = [FIRInstallations installationsWithApp:firebaseApp];
+ [installations authTokenForcingRefresh:forceRefresh
+ completion:^(FIRInstallationsAuthTokenResult *_Nullable token,
+ NSError *_Nullable error) {
+ if (error != nil) {
+ // Handle any errors if the token was not retrieved.
+ DLog(@"Unable to retrieve Installations auth token: %@", error);
+ [RNFBSharedUtils
+ rejectPromiseWithUserInfo:reject
+ userInfo:(NSMutableDictionary *)@{
+ @"code" : @"token-error",
+ @"message" : [error localizedDescription],
+ }];
+ return;
+ }
+ if (token == nil) {
+ DLog(@"Unable to retrieve Installations auth token.");
+ [RNFBSharedUtils
+ rejectPromiseWithUserInfo:reject
+ userInfo:(NSMutableDictionary *)@{
+ @"code" : @"token-null",
+ @"message" : @"no token fetched",
+ }];
+ return;
+ }
+
+ resolve(token.authToken);
+ }];
+}
+
+@end
diff --git a/packages/installations/lib/index.d.ts b/packages/installations/lib/index.d.ts
new file mode 100644
index 0000000000..834289ca2b
--- /dev/null
+++ b/packages/installations/lib/index.d.ts
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { ReactNativeFirebase } from '@react-native-firebase/app';
+
+/**
+ * Firebase Installations package for React Native.
+ *
+ * #### Example 1
+ *
+ * Access the firebase export from the `installations` package:
+ *
+ * ```js
+ * import { firebase } from '@react-native-firebase/installations';
+ *
+ * // firebase.installations().X
+ * ```
+ *
+ * #### Example 2
+ *
+ * Using the default export from the `installations` package:
+ *
+ * ```js
+ * import installations from '@react-native-firebase/installations';
+ *
+ * // installations().X
+ * ```
+ *
+ * #### Example 3
+ *
+ * Using the default export from the `app` package:
+ *
+ * ```js
+ * import firebase from '@react-native-firebase/app';
+ * import '@react-native-firebase/installations';
+ *
+ * // firebase.installations().X
+ * ```
+ *
+ * @firebase installations
+ */
+export namespace FirebaseInstallationsTypes {
+ import FirebaseModule = ReactNativeFirebase.FirebaseModule;
+
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
+ export interface Statics {
+ // firebase.installations.* static props go here
+ }
+
+ /**
+ * The Firebase Installations service is available for the default app or a given app.
+ *
+ * #### Example 1
+ *
+ * Get the installations instance for the **default app**:
+ *
+ * ```js
+ * const installationsForDefaultApp = firebase.installations();
+ * ```
+ *
+ * #### Example 2
+ *
+ * Get the installations instance for a **secondary app**:
+ *Ëš
+ * ```js
+ * const otherApp = firebase.app('otherApp');
+ * const installationsForOtherApp = firebase.installations(otherApp);
+ * ```
+ *
+ */
+ export class Module extends FirebaseModule {
+ /**
+ * Creates a Firebase Installation if there isn't one for the app and
+ * returns the Installation ID. The installation ID is a globally unique,
+ * stable, URL-safe base64 string identifier that uniquely identifies the app instance.
+ * NOTE: If the application already has an existing FirebaseInstanceID then the InstanceID identifier will be used.
+ *
+ * @return Firebase Installation ID, this is a url-safe base64 string of a 128-bit integer.
+ */
+ getId(): Promise;
+
+ /**
+ * Retrieves (locally or from the server depending on forceRefresh value) a valid installation auth token.
+ * An existing token may be invalidated or expire, so it is recommended to fetch the installation auth token
+ * before any request to external servers (it will be refreshed automatically for firebase API calls).
+ * This method should be used with forceRefresh == YES when e.g. a request with the previously fetched
+ * installation auth token failed with “Not Authorized” error.
+ *
+ * @param forceRefresh Options to get an auth token either by force refreshing or not.
+ * @return Firebase Installation Authentication Token
+ */
+ getToken(forceRefresh?: boolean): Promise;
+
+ /**
+ * Deletes the Firebase Installation and all associated data from the Firebase backend.
+ * This call may cause Firebase Cloud Messaging, Firebase Remote Config, Firebase Predictions,
+ * or Firebase In-App Messaging to not function properly. Fetching a new installations ID should
+ * reset all of the dependent services to a stable state again. A network connection is required
+ * for the method to succeed. If it fails, the existing installation data remains untouched.
+ */
+ delete(): Promise;
+
+ /**
+ * TODO implement id change listener for android.
+ *
+ * Sets a new callback that will get called when Installlation ID changes.
+ * Returns an unsubscribe function that will remove the callback when called.
+ * Only the Android SDK supports sending ID change events.
+ *
+ * @android
+ */
+ // onIdChange(callback: (installationId: string) => void): () => void;
+ }
+}
+
+declare const defaultExport: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp<
+ Installations.Module,
+ Installations.Statics
+>;
+
+export const firebase: ReactNativeFirebase.Module & {
+ installations: typeof defaultExport;
+ app(
+ name?: string,
+ ): ReactNativeFirebase.FirebaseApp & { installations(): FirebaseInstallationsTypes.Module };
+};
+
+export default defaultExport;
+
+/**
+ * Attach namespace to `firebase.` and `FirebaseApp.`.
+ */
+declare module '@react-native-firebase/app' {
+ namespace ReactNativeFirebase {
+ import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp;
+ interface Module {
+ installations: FirebaseModuleWithStaticsAndApp<
+ FirebaseInstallationsTypes.Module,
+ FirebaseInstallationsTypes.Statics
+ >;
+ }
+ interface FirebaseApp {
+ installations(): FirebaseInstallationsTypes.Module;
+ }
+ }
+}
diff --git a/packages/installations/lib/index.js b/packages/installations/lib/index.js
new file mode 100644
index 0000000000..cc00baddca
--- /dev/null
+++ b/packages/installations/lib/index.js
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016-present Invertase Limited & Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this library except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { isIOS } from '@react-native-firebase/app/lib/common';
+import {
+ createModuleNamespace,
+ FirebaseModule,
+ getFirebaseRoot,
+} from '@react-native-firebase/app/lib/internal';
+
+import version from './version';
+
+const statics = {};
+
+const namespace = 'installations';
+
+const nativeModuleName = 'RNFBInstallationsModule';
+
+class FirebaseInstallationsModule extends FirebaseModule {
+ getId() {
+ return this.native.getId();
+ }
+
+ getToken(forceRefresh) {
+ if (!forceRefresh) {
+ return this.native.getToken(false);
+ } else {
+ return this.native.getToken(true);
+ }
+ }
+
+ delete() {
+ return this.native.delete();
+ }
+
+ onIdChange() {
+ if (isIOS) {
+ return () => {};
+ }
+
+ // TODO implement change listener on Android
+ return () => {};
+ }
+}
+
+// import { SDK_VERSION } from '@react-native-firebase/installations';
+export const SDK_VERSION = version;
+
+// import installations from '@react-native-firebase/installations';
+// installations().X(...);
+export default createModuleNamespace({
+ statics,
+ version,
+ namespace,
+ nativeModuleName,
+ nativeEvents: false, // TODO implement android id change listener: ['installations_id_changed'],
+ hasMultiAppSupport: true,
+ hasCustomUrlOrRegionSupport: false,
+ ModuleClass: FirebaseInstallationsModule,
+});
+
+// import installations, { firebase } from '@react-native-firebase/installations';
+// installations().X(...);
+// firebase.installations().X(...);
+export const firebase = getFirebaseRoot();
diff --git a/packages/installations/package.json b/packages/installations/package.json
new file mode 100644
index 0000000000..eb1ebb5069
--- /dev/null
+++ b/packages/installations/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "@react-native-firebase/installations",
+ "version": "12.6.1",
+ "author": "Invertase (http://invertase.io)",
+ "description": "React Native Firebase - Installations",
+ "main": "lib/index.js",
+ "types": "lib/index.d.ts",
+ "scripts": {
+ "build": "genversion --semi lib/version.js",
+ "build:clean": "rimraf android/build && rimraf ios/build",
+ "prepare": "yarn run build"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/invertase/react-native-firebase/tree/master/packages/installations"
+ },
+ "license": "Apache-2.0",
+ "keywords": [
+ "react",
+ "react-native",
+ "firebase",
+ "installations"
+ ],
+ "peerDependencies": {
+ "@react-native-firebase/app": "12.6.1"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+}
diff --git a/packages/installations/type-test.ts b/packages/installations/type-test.ts
new file mode 100644
index 0000000000..a0d0f17120
--- /dev/null
+++ b/packages/installations/type-test.ts
@@ -0,0 +1,26 @@
+import firebase from '@react-native-firebase/app';
+import defaultExport, { firebase as firebaseFromModule } from '@react-native-firebase/installations';
+
+// checks module exists at root
+console.log(firebase.installations().app.name);
+
+// checks module exists at app level
+console.log(firebase.app().installations().app.name);
+
+// checks statics exist
+console.log(firebase.installations.SDK_VERSION);
+
+// checks statics exist on defaultExport
+console.log(defaultExport.SDK_VERSION);
+
+// checks root exists
+console.log(firebase.SDK_VERSION);
+
+// checks firebase named export exists on module
+console.log(firebaseFromModule.SDK_VERSION);
+
+// checks multi-app support exists
+console.log(firebase.installations(firebase.app()).app.name);
+
+// checks default export supports app arg
+console.log(defaultExport(firebase.app()).app.name);
diff --git a/tests/app.js b/tests/app.js
index 51fa792f13..03ff6abb04 100644
--- a/tests/app.js
+++ b/tests/app.js
@@ -27,6 +27,7 @@ import '@react-native-firebase/dynamic-links';
import '@react-native-firebase/firestore';
import '@react-native-firebase/functions';
import '@react-native-firebase/in-app-messaging';
+import '@react-native-firebase/installations';
import '@react-native-firebase/messaging';
import '@react-native-firebase/ml';
import '@react-native-firebase/perf';
diff --git a/tests/e2e/.mocharc.js b/tests/e2e/.mocharc.js
index b3e23fe121..89631fb6ac 100644
--- a/tests/e2e/.mocharc.js
+++ b/tests/e2e/.mocharc.js
@@ -24,6 +24,7 @@ module.exports = {
'../packages/messaging/e2e/**/*.e2e.js',
'../packages/ml/e2e/**/*.e2e.js',
'../packages/in-app-messaging/e2e/**/*.e2e.js',
+ '../packages/installations/e2e/**/*.e2e.js',
'../packages/remote-config/e2e/**/*.e2e.js',
'../packages/storage/e2e/**/*.e2e.js',
],
diff --git a/tests/ios/Podfile.lock b/tests/ios/Podfile.lock
index 7e21b867d7..3a33702120 100644
--- a/tests/ios/Podfile.lock
+++ b/tests/ios/Podfile.lock
@@ -385,6 +385,9 @@ PODS:
- Firebase/InAppMessaging (8.5.0):
- Firebase/CoreOnly
- FirebaseInAppMessaging (~> 8.5.0-beta)
+ - Firebase/Installations (8.5.0):
+ - Firebase/CoreOnly
+ - FirebaseInstallations (~> 8.5.0)
- Firebase/Messaging (8.5.0):
- Firebase/CoreOnly
- FirebaseMessaging (~> 8.5.0)
@@ -397,7 +400,7 @@ PODS:
- Firebase/Storage (8.5.0):
- Firebase/CoreOnly
- FirebaseStorage (~> 8.5.0)
- - FirebaseABTesting (8.5.0):
+ - FirebaseABTesting (8.6.0):
- FirebaseCore (~> 8.0)
- FirebaseAnalytics (8.5.0):
- FirebaseAnalytics/AdIdSupport (= 8.5.0)
@@ -430,7 +433,7 @@ PODS:
- FirebaseCoreDiagnostics (~> 8.0)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/Logger (~> 7.4)
- - FirebaseCoreDiagnostics (8.5.0):
+ - FirebaseCoreDiagnostics (8.6.0):
- GoogleDataTransport (~> 9.0)
- GoogleUtilities/Environment (~> 7.4)
- GoogleUtilities/Logger (~> 7.4)
@@ -517,25 +520,25 @@ PODS:
- GoogleUtilities/Environment (~> 7.2)
- nanopb (~> 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- - GoogleUtilities/AppDelegateSwizzler (7.5.0):
+ - GoogleUtilities/AppDelegateSwizzler (7.5.1):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- - GoogleUtilities/Environment (7.5.0):
+ - GoogleUtilities/Environment (7.5.1):
- PromisesObjC (< 3.0, >= 1.2)
- - GoogleUtilities/ISASwizzler (7.5.0)
- - GoogleUtilities/Logger (7.5.0):
+ - GoogleUtilities/ISASwizzler (7.5.1)
+ - GoogleUtilities/Logger (7.5.1):
- GoogleUtilities/Environment
- - GoogleUtilities/MethodSwizzler (7.5.0):
+ - GoogleUtilities/MethodSwizzler (7.5.1):
- GoogleUtilities/Logger
- - GoogleUtilities/Network (7.5.0):
+ - GoogleUtilities/Network (7.5.1):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- - "GoogleUtilities/NSData+zlib (7.5.0)"
- - GoogleUtilities/Reachability (7.5.0):
+ - "GoogleUtilities/NSData+zlib (7.5.1)"
+ - GoogleUtilities/Reachability (7.5.1):
- GoogleUtilities/Logger
- - GoogleUtilities/UserDefaults (7.5.0):
+ - GoogleUtilities/UserDefaults (7.5.1):
- GoogleUtilities/Logger
- "gRPC-C++ (1.28.2)":
- "gRPC-C++/Implementation (= 1.28.2)"
@@ -829,62 +832,66 @@ PODS:
- React-cxxreact (= 0.64.2)
- React-jsi (= 0.64.2)
- React-perflogger (= 0.64.2)
- - RNFBAnalytics (12.6.0):
+ - RNFBAnalytics (12.6.1):
- Firebase/Analytics (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBApp (12.6.0):
+ - RNFBApp (12.6.1):
- Firebase/CoreOnly (= 8.5.0)
- React-Core
- - RNFBAppCheck (12.6.0):
+ - RNFBAppCheck (12.6.1):
- Firebase/AppCheck (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBAuth (12.6.0):
+ - RNFBAuth (12.6.1):
- Firebase/Auth (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBCrashlytics (12.6.0):
+ - RNFBCrashlytics (12.6.1):
- Firebase/Crashlytics (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBDatabase (12.6.0):
+ - RNFBDatabase (12.6.1):
- Firebase/Database (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBDynamicLinks (12.6.0):
+ - RNFBDynamicLinks (12.6.1):
- Firebase/DynamicLinks (= 8.5.0)
- GoogleUtilities/AppDelegateSwizzler
- React-Core
- RNFBApp
- - RNFBFirestore (12.6.0):
+ - RNFBFirestore (12.6.1):
- Firebase/Firestore (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBFunctions (12.6.0):
+ - RNFBFunctions (12.6.1):
- Firebase/Functions (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBInAppMessaging (12.6.0):
+ - RNFBInAppMessaging (12.6.1):
- Firebase/InAppMessaging (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBMessaging (12.6.0):
+ - RNFBInstallations (12.6.1):
+ - Firebase/Installations (= 8.5.0)
+ - React-Core
+ - RNFBApp
+ - RNFBMessaging (12.6.1):
- Firebase/Messaging (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBML (12.6.0):
+ - RNFBML (12.6.1):
- React-Core
- RNFBApp
- - RNFBPerf (12.6.0):
+ - RNFBPerf (12.6.1):
- Firebase/Performance (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBRemoteConfig (12.6.0):
+ - RNFBRemoteConfig (12.6.1):
- Firebase/RemoteConfig (= 8.5.0)
- React-Core
- RNFBApp
- - RNFBStorage (12.6.0):
+ - RNFBStorage (12.6.1):
- Firebase/Storage (= 8.5.0)
- React-Core
- RNFBApp
@@ -931,6 +938,7 @@ DEPENDENCIES:
- RNFBFirestore (from `../../packages/firestore`)
- RNFBFunctions (from `../../packages/functions`)
- RNFBInAppMessaging (from `../../packages/in-app-messaging`)
+ - RNFBInstallations (from `../../packages/installations`)
- RNFBMessaging (from `../../packages/messaging`)
- RNFBML (from `../../packages/ml`)
- RNFBPerf (from `../../packages/perf`)
@@ -1049,6 +1057,8 @@ EXTERNAL SOURCES:
:path: "../../packages/functions"
RNFBInAppMessaging:
:path: "../../packages/in-app-messaging"
+ RNFBInstallations:
+ :path: "../../packages/installations"
RNFBMessaging:
:path: "../../packages/messaging"
RNFBML:
@@ -1070,12 +1080,12 @@ SPEC CHECKSUMS:
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
FBReactNativeSpec: 25e094945df743fcfa1283399bf9715648bff333
Firebase: ff8c73105b90e33e1dc6c8e5445d7adc2ccdc7c1
- FirebaseABTesting: f7cb3fbed1c5bd3e733a79d9955447be3f3b06a5
+ FirebaseABTesting: c3e48ebf5e7e5c674c5a131c68e941d7921d83dc
FirebaseAnalytics: 96325c1e0acbd2bb805c6a613028b1fe599d6a37
FirebaseAppCheck: 0cced04f86b12f8b72d0a6437a7a4cf76e2ecc07
FirebaseAuth: b152ea261b60eeb9419ae7e5bf34761382b33277
FirebaseCore: 1c1ca72483b59b17050f5b4cec4fb748425a3901
- FirebaseCoreDiagnostics: 7bf55d386f9fc690d971b70a582142321a390eb8
+ FirebaseCoreDiagnostics: 3721920bde3a9a6d5aa093c1d25e9d3e47f694af
FirebaseCrashlytics: 8e7cf678cb149d421198388c6fc3d3acfd266539
FirebaseDatabase: 65c3742ed355f9b9db222036fd154e699ab7d672
FirebaseDynamicLinks: 6e406b3bb669f8c8a63e7254bb63251fa3f88a43
@@ -1090,7 +1100,7 @@ SPEC CHECKSUMS:
glog: 73c2498ac6884b13ede40eda8228cb1eee9d9d62
GoogleAppMeasurement: 8d10c1c470fcb0e5143ed74fddd164f0a0384800
GoogleDataTransport: 85fd18ff3019bb85d3f2c551d04c481dedf71fc9
- GoogleUtilities: eea970f4a389963963bffe8d8fabe43540678b9c
+ GoogleUtilities: 3df19e3c24f7bbc291d8b5809aa6b0d41e642437
"gRPC-C++": 13d8ccef97d5c3c441b7e3c529ef28ebee86fad2
gRPC-Core: 4afa11bfbedf7cdecd04de535a9e046893404ed5
GTMSessionFetcher: 36689134877faeb055b27dfa4ccc9ceaa42e029e
@@ -1122,21 +1132,22 @@ SPEC CHECKSUMS:
React-RCTVibration: 24600e3b1aaa77126989bc58b6747509a1ba14f3
React-runtimeexecutor: a9904c6d0218fb9f8b19d6dd88607225927668f9
ReactCommon: 149906e01aa51142707a10665185db879898e966
- RNFBAnalytics: d176dc0b499a7d61a0a713d596742282c50a36d3
- RNFBApp: 6fbdb0d684c16507c4eb51689d4ff4cfef3bf11f
- RNFBAppCheck: 591b7fc417c0df45c4096335b0bd298b30825c42
- RNFBAuth: 352fddc14c7de4fcac69b12c821e20212845d974
- RNFBCrashlytics: 629aeb5619dd7501a28a3be42d0728de8f3d7bf8
- RNFBDatabase: b5a92ea365161fef1c522b644ad2f723de6bf3fd
- RNFBDynamicLinks: ef3c14bff6d716959999119161924005227e9059
- RNFBFirestore: b817db23e6cc021e60644efc04803be807fb07f1
- RNFBFunctions: 5cafd47980bca562d7c6175fde7aca154bb9ff77
- RNFBInAppMessaging: 7beecf33a06164b0de5a7f3744570c145d2b3e3b
- RNFBMessaging: 18158b22e06e2297df9628486193455eb619b46d
- RNFBML: 0742fa4815d7f9576c5d13b270fed7a51d1d030d
- RNFBPerf: 5d5d4a6a8a5506703c119b8742e8a12a5af2caa9
- RNFBRemoteConfig: 60c686bd4e6227ac5a013378be2f2e34d76c7803
- RNFBStorage: 8084581b1133aa14267f6cc6272d9d22f4470b08
+ RNFBAnalytics: c546bf14fbf0a19f0801890dc8569efd7e7892ba
+ RNFBApp: 169c26e7f857173bd17b3eb5aba4e80bab598b76
+ RNFBAppCheck: 6c135d623d954f47e83f7b05654ab0deaabe3c1f
+ RNFBAuth: 018b6408d969c734455e72d508400be021ceafa3
+ RNFBCrashlytics: e9026dec158d1d1bb303e6f01fc712aeee1b6fbb
+ RNFBDatabase: bcfffc8c1bcc595decb7567d2bce305d6e2ce5a5
+ RNFBDynamicLinks: 92cd6c4ba5edef4d37a927d09122aeccda1def0e
+ RNFBFirestore: 2b5601224411db7f3ada77c286d299094f56caee
+ RNFBFunctions: 6376a08f448bc8f40ce6bf2459fb4282cc79dffa
+ RNFBInAppMessaging: 6f2b66ab43952da1fc91711774454cdefce2931d
+ RNFBInstallations: e6dd6113016a96518177a2e1eb170c4bf44e8c17
+ RNFBMessaging: 5ceb208f9b65941db520be903cbd778f7ebd0065
+ RNFBML: dd88f4f3ab120c48737ff3fbe07c2ba5ece1e5d9
+ RNFBPerf: f2db4bed596bba3697a6bd8f801a592b21990fe2
+ RNFBRemoteConfig: 2e2c2df520233083918647752a9b41a54aada45a
+ RNFBStorage: e4ddd8a58cf28a7f67876d6298d19273c1fd65e4
Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac
PODFILE CHECKSUM: c61aa64b498060e6a9470f21629e95b1ece6f524
diff --git a/tests/package.json b/tests/package.json
index ef95336f3c..7737446863 100644
--- a/tests/package.json
+++ b/tests/package.json
@@ -18,6 +18,7 @@
"@react-native-firebase/firestore": "12.6.1",
"@react-native-firebase/functions": "12.6.1",
"@react-native-firebase/in-app-messaging": "12.6.1",
+ "@react-native-firebase/installations": "12.6.1",
"@react-native-firebase/messaging": "12.6.1",
"@react-native-firebase/ml": "12.6.1",
"@react-native-firebase/perf": "12.6.1",
diff --git a/website/scripts/source-reference.js b/website/scripts/source-reference.js
index e8df4fb7cd..82df859b22 100644
--- a/website/scripts/source-reference.js
+++ b/website/scripts/source-reference.js
@@ -165,6 +165,8 @@ function moduleNameToFullName(name) {
return 'Instance ID';
case 'in-app-messaging':
return 'In-App Messaging';
+ case 'installations':
+ return 'Installations';
case 'messaging':
return 'Cloud Messaging';
case 'ml':
diff --git a/website/src/templates/utils.ts b/website/src/templates/utils.ts
index 0bced9c3b1..91c7772052 100644
--- a/website/src/templates/utils.ts
+++ b/website/src/templates/utils.ts
@@ -47,6 +47,8 @@ function iconForModule(module: string): string {
return '//static.invertase.io/assets/firebase/dynamic-links.svg';
case 'in-app-messaging':
return '//static.invertase.io/assets/firebase/in-app-messaging.svg';
+ case 'installations':
+ return '//static.invertase.io/assets/social/firebase-logo.png';
case 'ml':
return '//static.invertase.io/assets/firebase/ml-kit.svg';
case 'remote-config':