Skip to content

Commit

Permalink
feat(firebase_app_check): provide androidDebugProvider boolean for …
Browse files Browse the repository at this point in the history
…android debug provider & update app check example app (#9412)
  • Loading branch information
russellwheatley committed Sep 28, 2022
1 parent e61b603 commit f1f2674
Show file tree
Hide file tree
Showing 15 changed files with 91 additions and 24 deletions.
Expand Up @@ -51,9 +51,9 @@ android {
api firebaseCoreProject
implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}")
// TODO: Since App Check is a beta SDK it's not available in the Firebase Android BoM so we need to specify an exact version here.
implementation 'com.google.firebase:firebase-appcheck-safetynet:16.0.0-beta04'
implementation 'com.google.firebase:firebase-appcheck-debug:16.0.0-beta04'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'com.google.firebase:firebase-appcheck-safetynet:16.0.2'
implementation 'com.google.firebase:firebase-appcheck-debug:16.0.2'
implementation 'androidx.annotation:annotation:1.5.0'
}
}

Expand Down
Expand Up @@ -14,6 +14,7 @@
import com.google.firebase.FirebaseApp;
import com.google.firebase.appcheck.AppCheckTokenResult;
import com.google.firebase.appcheck.FirebaseAppCheck;
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory;
import com.google.firebase.appcheck.safetynet.SafetyNetAppCheckProviderFactory;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.BinaryMessenger;
Expand Down Expand Up @@ -77,9 +78,17 @@ private Task<Void> activate(Map<String, Object> arguments) {
cachedThreadPool.execute(
() -> {
try {
FirebaseAppCheck firebaseAppCheck = getAppCheck(arguments);
firebaseAppCheck.installAppCheckProviderFactory(
SafetyNetAppCheckProviderFactory.getInstance());
Boolean debug = (Boolean) arguments.get("androidDebugProvider");

if (Boolean.TRUE.equals(debug)) {
FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance());
} else {
FirebaseAppCheck firebaseAppCheck = getAppCheck(arguments);
firebaseAppCheck.installAppCheckProviderFactory(
SafetyNetAppCheckProviderFactory.getInstance());
}
taskCompletionSource.setResult(null);
} catch (Exception e) {
taskCompletionSource.setException(e);
Expand Down
Expand Up @@ -28,15 +28,16 @@ apply plugin: 'com.google.gms.google-services'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion 30
compileSdkVersion 33

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.flutter.plugins.firebase.appcheck.example"
minSdkVersion 16
targetSdkVersion 30
minSdkVersion 19
targetSdkVersion 33
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
}

buildTypes {
Expand Down
Expand Up @@ -9,7 +9,9 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="adjustResize"
android:exported="true"
>
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
Expand Down
@@ -1,21 +1,21 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:4.1.2'
classpath 'com.android.tools.build:gradle:4.1.3'
// START: FlutterFire Configuration
classpath 'com.google.gms:google-services:4.3.10'
classpath 'com.google.gms:google-services:4.3.13'
// END: FlutterFire Configuration
}
}

allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand Down
Expand Up @@ -2,6 +2,7 @@ import 'package:firebase_app_check/firebase_app_check.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

import 'firebase_options.dart';

Expand All @@ -17,6 +18,7 @@ Future<void> main() async {
// Your personal reCaptcha public key goes here:
.activate(
webRecaptchaSiteKey: kWebRecaptchaSiteKey,
androidDebugProvider: true,
);

runApp(MyApp());
Expand Down Expand Up @@ -79,6 +81,25 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () async {
// Use this button to check whether the request was validated on the Firebase console
// Gets first document in collection
final result = await FirebaseFirestore.instance
.collection('flutter-tests')
.limit(1)
.get();

if (result.docs.isNotEmpty) {
setMessage('Document found');
} else {
setMessage(
'Document not found, please add a document to the collection',
);
}
},
child: const Text('Test App Check validates requests'),
),
ElevatedButton(
onPressed: () async {
if (kIsWeb) {
Expand All @@ -88,6 +109,7 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
}
await appCheck.activate(
webRecaptchaSiteKey: kWebRecaptchaSiteKey,
androidDebugProvider: true,
);
setMessage('activated!!');
},
Expand Down
Expand Up @@ -9,6 +9,8 @@ environment:
sdk: ">=2.16.0 <3.0.0"

dependencies:
cloud_firestore:
path: ../../../cloud_firestore/cloud_firestore
cupertino_icons: ^0.1.2
firebase_app_check:
path: ../
Expand All @@ -18,6 +20,12 @@ dependencies:
sdk: flutter

dependency_overrides:
cloud_firestore:
path: ../../../cloud_firestore/cloud_firestore
cloud_firestore_platform_interface:
path: ../../../cloud_firestore/cloud_firestore_platform_interface
cloud_firestore_web:
path: ../../../cloud_firestore/cloud_firestore_web
firebase_app_check_platform_interface:
path: ../../../firebase_app_check/firebase_app_check_platform_interface
firebase_app_check_web:
Expand All @@ -28,6 +36,5 @@ dependency_overrides:
path: ../../../firebase_core/firebase_core_platform_interface
firebase_core_web:
path: ../../../firebase_core/firebase_core_web

flutter:
uses-material-design: true
Expand Up @@ -52,8 +52,14 @@ class FirebaseAppCheck extends FirebasePluginPlatform {
/// On web, provide the reCAPTCHA v3 Site Key which can be found in the
/// Firebase Console. For more information, see
/// [the Firebase Documentation](https://firebase.google.com/docs/app-check/web).
Future<void> activate({String? webRecaptchaSiteKey}) {
return _delegate.activate(webRecaptchaSiteKey: webRecaptchaSiteKey);
///
/// On Android, you may set androidDebugProvider to "true" to use the debug provider
/// For more information, see [the Firebase Documentation](https://firebase.google.com/docs/app-check/android/debug-provider)
Future<void> activate(
{String? webRecaptchaSiteKey, bool? androidDebugProvider = false}) {
return _delegate.activate(
webRecaptchaSiteKey: webRecaptchaSiteKey,
androidDebugProvider: androidDebugProvider);
}

/// Get the current App Check token.
Expand Down
Expand Up @@ -55,7 +55,10 @@ void main() {

group('activate', () {
test('successful call', () async {
await appCheck.activate(webRecaptchaSiteKey: 'key');
await appCheck.activate(
webRecaptchaSiteKey: 'key',
androidDebugProvider: true,
);

expect(
methodCallLog,
Expand All @@ -64,6 +67,7 @@ void main() {
'FirebaseAppCheck#activate',
arguments: <String, dynamic>{
'appName': defaultFirebaseAppName,
'androidDebugProvider': true,
},
)
],
Expand Down
Expand Up @@ -3,8 +3,10 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:io';

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

import '../../firebase_app_check_platform_interface.dart';
Expand Down Expand Up @@ -69,10 +71,15 @@ class MethodChannelFirebaseAppCheck extends FirebaseAppCheckPlatform {
}

@override
Future<void> activate({String? webRecaptchaSiteKey}) async {
Future<void> activate({
String? webRecaptchaSiteKey,
bool? androidDebugProvider,
}) async {
try {
await channel.invokeMethod<void>('FirebaseAppCheck#activate', {
'appName': app.name,
if (Platform.isAndroid || kDebugMode)
'androidDebugProvider': androidDebugProvider,
});
} on PlatformException catch (e, s) {
throw platformExceptionToFirebaseException(e, s);
Expand Down
Expand Up @@ -58,7 +58,8 @@ abstract class FirebaseAppCheckPlatform extends PlatformInterface {
/// On web, provide the reCAPTCHA v3 Site Key which can be found in the
/// Firebase Console. For more information, see
/// [the Firebase Documentation](https://firebase.google.com/docs/app-check/web?authuser=0).
Future<void> activate({String? webRecaptchaSiteKey}) {
Future<void> activate(
{String? webRecaptchaSiteKey, bool? androidDebugProvider}) {
throw UnimplementedError('activate() is not implemented');
}

Expand Down
Expand Up @@ -67,13 +67,19 @@ void main() {
});

test('activate', () async {
await appCheck.activate(webRecaptchaSiteKey: 'test-key');
await appCheck.activate(
webRecaptchaSiteKey: 'test-key',
androidDebugProvider: true,
);
expect(
methodCallLogger,
<Matcher>[
isMethodCall(
'FirebaseAppCheck#activate',
arguments: {'appName': defaultFirebaseAppName},
arguments: {
'appName': defaultFirebaseAppName,
'androidDebugProvider': true
},
),
],
);
Expand Down
Expand Up @@ -60,7 +60,8 @@ class FirebaseAppCheckWeb extends FirebaseAppCheckPlatform {
}

@override
Future<void> activate({String? webRecaptchaSiteKey}) async {
Future<void> activate(
{String? webRecaptchaSiteKey, bool? androidDebugProvider}) async {
// activate API no longer exists, recaptcha key has to be passed on initialization of app-check instance.
return convertWebExceptions<Future<void>>(() async {
_webAppCheck ??= app_check_interop.getAppCheckInstance(
Expand Down
2 changes: 1 addition & 1 deletion tests/android/build.gradle
@@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.5.20'
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
Expand Down
Expand Up @@ -23,6 +23,7 @@ void setupTests() {
await expectLater(
FirebaseAppCheck.instance.activate(
webRecaptchaSiteKey: '6Lemcn0dAAAAABLkf6aiiHvpGD6x-zF3nOSDU2M8',
androidDebugProvider: true,
),
completes,
);
Expand Down

0 comments on commit f1f2674

Please sign in to comment.