Skip to content

Commit cd28e54

Browse files
committed
feat(app-check): implement AppCheck module
1 parent b710657 commit cd28e54

40 files changed

+1964
-32
lines changed

docs/analytics/screen-tracking.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Screen Tracking
33
description: Setup Firebase Analytics to track your in-app screen flow.
44
previous: /analytics/usage
5-
next: /
5+
next: /app-check/usage
66
---
77

88
Standard React Native applications run inside a single `Activity`/`ViewController`, meaning any screen changes won't be

docs/app-check/usage/usage.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
title: AppCheck
3+
description: Installation and getting started with AppCheck.
4+
icon: //static.invertase.io/assets/social/firebase-logo.png
5+
next: /auth/usage
6+
previous: /analytics/screen-tracking
7+
---
8+
9+
# Installation
10+
11+
This module requires that the `@react-native-firebase/app` module is already setup and installed. To install the "app"
12+
module, view the [Getting Started](/) documentation.
13+
14+
```bash
15+
# Install & setup the app module
16+
yarn add @react-native-firebase/app
17+
18+
# Install the app-check module
19+
yarn add @react-native-firebase/app-check
20+
21+
# If you're developing your app using iOS, run this command
22+
cd ios/ && pod install
23+
```
24+
25+
AppCheck requires you set the minimum iOS Deployment version in `ios/Podfile` to `11.0` or greater.
26+
27+
# What does it do
28+
29+
App Check works alongside other Firebase services to help protect your backend resources from abuse, such as billing fraud or phishing. With App Check, devices running your app will use an app or device attestation provider that attests to one or both of the following:
30+
31+
- Requests originate from your authentic app
32+
- Requests originate from an authentic, untampered device
33+
34+
This attestation is attached to every request your app makes to your Firebase backend resources.
35+
36+
<Youtube id="Fjj4fmr2t04" />
37+
38+
This App Check module has built-in support for using the following services as attestation providers:
39+
40+
- DeviceCheck on iOS
41+
- SafetyNet on Android
42+
43+
App Check currently works with the following Firebase products:
44+
45+
- Realtime Database
46+
- Cloud Storage
47+
- Cloud Functions (callable functions)
48+
49+
The [official Firebase AppCheck documentation](https://firebase.google.com/docs/app-check) has more information, including about the iOS AppAttest provider, and testing/ CI integration, it is worth a read.
50+
51+
# Usage
52+
53+
## Activate
54+
55+
On iOS if you include the AppCheck package, it is activated by default. The only configuration possible is the token auto refresh. When you call activate, the provider (DeviceCheck by default) stays the same but the token auto refresh setting will be changed based on the argument provided.
56+
57+
On Android, AppCheck is not activated until you call the activate method. The provider is not configurable here either but if your app is "debuggable", then the Debug app check provider will be installed, otherwise the SafetyNet provider will be installed.
58+
59+
You must call activate prior to calling any firebase back-end services for AppCheck to function.
60+
61+
## Automatic Data Collection
62+
63+
AppCheck has an "tokenAutoRefreshEnabled" setting. This may cause AppCheck to attempt a remote AppCheck token fetch prior to user consent. In certain scenarios, like those that exist in GDPR-compliant apps running for the first time, this may be unwanted.
64+
65+
If unset, the "tokenAutoRefreshEnabled" setting will defer to the app's "automatic data collection" setting, which may be set in the Info.plist or AndroidManifest.xml
66+
67+
## Using AppCheck tokens for non-firebase services
68+
69+
The [official documentation](https://firebase.google.com/docs/app-check/web/custom-resource) shows how to use `getToken` to access the current AppCheck token and then verify it in external services.
70+
71+
## Testing Environments / CI
72+
73+
AppCheck may be used in CI environments by following the upstream documentation to configure a debug token shared with your app in the CI environment.
74+
75+
In certain react-native testing scenarios it may be difficult to access the shared secret, but the react-native-firebase testing app for e2e testing does successfully fetch AppCheck tokens via:
76+
77+
- including the AppCheck debug test helper in the test app, along with a change to `DetoxTest` for Android
78+
- by setting an environment variable and initializing the debug provider before firebase configre in `AppDelegate.m` for iOS.

docs/app/usage.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ for manually initializing secondary Firebase app instances.
2121

2222
Currently, the native Firebase SDKs only provide functionality for creating secondary apps on the following services:
2323

24+
- [AppCheck](/app-check/usage).
2425
- [Authentication](/auth/usage).
2526
- [Realtime Database](/database/usage).
2627
- [Cloud Firestore](/firestore/usage).

docs/auth/usage/index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Authentication
33
description: Installation and getting started with Authentication.
44
icon: //static.invertase.io/assets/firebase/authentication.svg
55
next: /auth/social-auth
6-
previous: /analytics/screen-tracking
6+
previous: /app-check/usage
77
---
88

99
# Installation

docs/sidebar.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
- - Building an Analytics Funnel
2424
- 'https://blog.theodo.com/2018/01/building-google-analytics-funnel-firebase-react-native'
2525
- '//static.invertase.io/assets/firebase/analytics.svg'
26+
- - AppCheck
27+
- - - Usage
28+
- '/app-check/usage'
29+
- '//static.invertase.io/assets/social/firebase-logo.png'
2630
- - Authentication
2731
- - - Usage
2832
- '/auth/usage'

package.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@
3434
"tests:android:test:jacoco-report": "cd tests/android && ./gradlew jacocoAndroidTestReport",
3535
"tests:ios:build": "cd tests && ./node_modules/.bin/detox build --configuration ios.sim.debug",
3636
"tests:ios:build-release": "cd tests && ./node_modules/.bin/detox build --configuration ios.sim.release",
37-
"tests:ios:test": "cd tests && ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn",
38-
"tests:ios:test:debug": "cd tests && ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn --inspect",
39-
"tests:ios:test-reuse": "cd tests && ./node_modules/.bin/detox test --configuration ios.sim.debug --reuse --loglevel warn",
40-
"tests:ios:test-cover": "cd tests && ./node_modules/.bin/nyc ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn",
41-
"tests:ios:test-cover-reuse": "cd tests && node_modules/.bin/nyc ./node_modules/.bin/detox test --configuration ios.sim.debug --reuse --loglevel warn",
37+
"tests:ios:test": "cd tests && SIMCTL_CHILD_FIRAAppCheckDebugToken=698956B2-187B-49C6-9E25-C3F3530EEBAF ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn",
38+
"tests:ios:test:debug": "cd tests && SIMCTL_CHILD_FIRAAppCheckDebugToken=698956B2-187B-49C6-9E25-C3F3530EEBAF ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn --inspect",
39+
"tests:ios:test-reuse": "cd tests && SIMCTL_CHILD_FIRAAppCheckDebugToken=\"698956B2-187B-49C6-9E25-C3F3530EEBAF\" ./node_modules/.bin/detox test --configuration ios.sim.debug --reuse --loglevel warn",
40+
"tests:ios:test-cover": "cd tests && SIMCTL_CHILD_FIRAAppCheckDebugToken=698956B2-187B-49C6-9E25-C3F3530EEBAF ./node_modules/.bin/nyc ./node_modules/.bin/detox test --configuration ios.sim.debug --loglevel warn",
41+
"tests:ios:test-cover-reuse": "cd tests && SIMCTL_CHILD_FIRAAppCheckDebugToken=698956B2-187B-49C6-9E25-C3F3530EEBAF node_modules/.bin/nyc ./node_modules/.bin/detox test --configuration ios.sim.debug --reuse --loglevel warn",
4242
"tests:ios:pod:install": "cd tests && cd ios && rm -rf ReactNativeFirebaseDemo.xcworkspace && rm -f Podfile.lock && pod install --repo-update && cd ..",
4343
"format:markdown": "prettier --write \"docs/**/*.md\""
4444
},

packages/app-check/.npmignore

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Built application files
2+
android/*/build/
3+
4+
# Crashlytics configuations
5+
android/com_crashlytics_export_strings.xml
6+
7+
# Local configuration file (sdk path, etc)
8+
android/local.properties
9+
10+
# Gradle generated files
11+
android/.gradle/
12+
13+
# Signing files
14+
android/.signing/
15+
16+
# User-specific configurations
17+
android/.idea/gradle.xml
18+
android/.idea/libraries/
19+
android/.idea/workspace.xml
20+
android/.idea/tasks.xml
21+
android/.idea/.name
22+
android/.idea/compiler.xml
23+
android/.idea/copyright/profiles_settings.xml
24+
android/.idea/encodings.xml
25+
android/.idea/misc.xml
26+
android/.idea/modules.xml
27+
android/.idea/scopes/scope_settings.xml
28+
android/.idea/vcs.xml
29+
android/*.iml
30+
31+
# Xcode
32+
*.pbxuser
33+
*.mode1v3
34+
*.mode2v3
35+
*.perspectivev3
36+
*.xcuserstate
37+
ios/Pods
38+
ios/build
39+
*project.xcworkspace*
40+
*xcuserdata*
41+
42+
# OS-specific files
43+
.DS_Store
44+
.DS_Store?
45+
._*
46+
.Spotlight-V100
47+
.Trashes
48+
ehthumbs.db
49+
Thumbs.dbandroid/gradle
50+
android/gradlew
51+
android/build
52+
android/gradlew.bat
53+
android/gradle/
54+
55+
.idea
56+
coverage
57+
yarn.lock
58+
e2e/
59+
.github
60+
.vscode
61+
.nyc_output
62+
android/.settings
63+
*.coverage.json
64+
.circleci
65+
.eslintignore

packages/app-check/LICENSE

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
Apache-2.0 License
2+
------------------
3+
4+
Copyright (c) 2016-present Invertase Limited <[email protected]> & Contributors
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this library except in compliance with the License.
8+
9+
You may obtain a copy of the Apache-2.0 License at
10+
11+
http://www.apache.org/licenses/LICENSE-2.0
12+
13+
Unless required by applicable law or agreed to in writing, software
14+
distributed under the License is distributed on an "AS IS" BASIS,
15+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
See the License for the specific language governing permissions and
17+
limitations under the License.
18+
19+
20+
Creative Commons Attribution 3.0 License
21+
----------------------------------------
22+
23+
Copyright (c) 2016-present Invertase Limited <[email protected]> & Contributors
24+
25+
Documentation and other instructional materials provided for this project
26+
(including on a separate documentation repository or it's documentation website) are
27+
licensed under the Creative Commons Attribution 3.0 License. Code samples/blocks
28+
contained therein are licensed under the Apache License, Version 2.0 (the "License"), as above.
29+
30+
You may obtain a copy of the Creative Commons Attribution 3.0 License at
31+
32+
https://creativecommons.org/licenses/by/3.0/

packages/app-check/README.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<p align="center">
2+
<a href="https://rnfirebase.io">
3+
<img width="160px" src="https://i.imgur.com/JIyBtKW.png"><br/>
4+
</a>
5+
<h2 align="center">React Native Firebase - AppCheck</h2>
6+
</p>
7+
8+
<p align="center">
9+
<a href="https://api.rnfirebase.io/coverage/app-check/detail"><img src="https://api.rnfirebase.io/coverage/app-check/badge?style=flat-square" alt="Coverage"></a>
10+
<a href="https://www.npmjs.com/package/@react-native-firebase/app-check"><img src="https://img.shields.io/npm/dm/@react-native-firebase/app-check.svg?style=flat-square" alt="NPM downloads"></a>
11+
<a href="https://www.npmjs.com/package/@react-native-firebase/app-check"><img src="https://img.shields.io/npm/v/@react-native-firebase/app-check.svg?style=flat-square" alt="NPM version"></a>
12+
<a href="/LICENSE"><img src="https://img.shields.io/npm/l/react-native-firebase.svg?style=flat-square" alt="License"></a>
13+
<a href="https://lerna.js.org/"><img src="https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg?style=flat-square" alt="Maintained with Lerna"></a>
14+
</p>
15+
16+
<p align="center">
17+
<a href="https://invertase.link/discord"><img src="https://img.shields.io/discord/295953187817521152.svg?style=flat-square&colorA=7289da&label=Chat%20on%20Discord" alt="Chat on Discord"></a>
18+
<a href="https://twitter.com/rnfirebase"><img src="https://img.shields.io/twitter/follow/rnfirebase.svg?style=flat-square&colorA=1da1f2&colorB=&label=Follow%20on%20Twitter" alt="Follow on Twitter"></a>
19+
<a href="https://www.facebook.com/groups/rnfirebase"><img src="https://img.shields.io/badge/Follow%20on%20Facebook-4172B8?logo=facebook&style=flat-square&logoColor=fff" alt="Follow on Facebook"></a>
20+
</p>
21+
22+
---
23+
24+
AppCheck description.
25+
26+
[> Learn More](https://firebase.google.com/products/app-check/)
27+
28+
## Installation
29+
30+
Requires `@react-native-firebase/app` to be installed.
31+
32+
```bash
33+
yarn add @react-native-firebase/app-check
34+
```
35+
36+
## Documentation
37+
38+
- [Guides](#TODO)
39+
- [Installation](#TODO)
40+
- [Reference](#TODO)
41+
42+
## License
43+
44+
- See [LICENSE](/LICENSE)
45+
46+
---
47+
48+
<p>
49+
<img align="left" width="75px" src="https://static.invertase.io/assets/invertase-logo-small.png">
50+
<p align="left">
51+
Built and maintained with 💛 by <a href="https://invertase.io">Invertase</a>.
52+
</p>
53+
</p>
54+
55+
---
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
require 'json'
2+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3+
appPackage = JSON.parse(File.read(File.join('..', 'app', 'package.json')))
4+
5+
coreVersionDetected = appPackage['version']
6+
coreVersionRequired = package['peerDependencies'][appPackage['name']]
7+
firebase_sdk_version = appPackage['sdkVersions']['ios']['firebase']
8+
if coreVersionDetected != coreVersionRequired
9+
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."
10+
end
11+
12+
Pod::Spec.new do |s|
13+
s.name = "RNFBAppCheck"
14+
s.version = package["version"]
15+
s.description = package["description"]
16+
s.summary = <<-DESC
17+
A well tested feature rich Firebase implementation for React Native, supporting iOS & Android.
18+
DESC
19+
s.homepage = "http://invertase.io/oss/react-native-firebase"
20+
s.license = package['license']
21+
s.authors = "Invertase Limited"
22+
s.source = { :git => "https://github.com/invertase/react-native-firebase.git", :tag => "v#{s.version}" }
23+
s.social_media_url = 'http://twitter.com/invertaseio'
24+
s.ios.deployment_target = "11.0"
25+
s.source_files = 'ios/**/*.{h,m}'
26+
27+
# React Native dependencies
28+
s.dependency 'React-Core'
29+
s.dependency 'RNFBApp'
30+
31+
if defined?($FirebaseSDKVersion)
32+
Pod::UI.puts "#{s.name}: Using user specified Firebase SDK version '#{$FirebaseSDKVersion}'"
33+
firebase_sdk_version = $FirebaseSDKVersion
34+
end
35+
36+
# Firebase dependencies
37+
s.dependency 'Firebase/AppCheck', firebase_sdk_version
38+
39+
if defined?($RNFirebaseAsStaticFramework)
40+
Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNFirebaseAsStaticFramework}'"
41+
s.static_framework = $RNFirebaseAsStaticFramework
42+
else
43+
s.static_framework = false
44+
end
45+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { firebase } from '../lib';
2+
3+
describe('appCheck()', function () {
4+
describe('namespace', function () {
5+
it('accessible from firebase.app()', function () {
6+
const app = firebase.app();
7+
expect(app.appCheck).toBeDefined();
8+
expect(app.appCheck().app).toEqual(app);
9+
});
10+
11+
it('supports multiple apps', async function () {
12+
expect(firebase.appCheck().app.name).toEqual('[DEFAULT]');
13+
expect(firebase.appCheck(firebase.app('secondaryFromNative')).app.name).toEqual(
14+
'secondaryFromNative',
15+
);
16+
expect(firebase.app('secondaryFromNative').appCheck().app.name).toEqual(
17+
'secondaryFromNative',
18+
);
19+
});
20+
});
21+
});
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# editorconfig
2+
root = true
3+
4+
[*]
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
charset = utf-8
9+
trim_trailing_whitespace = true
10+
insert_final_newline = true

0 commit comments

Comments
 (0)