Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ apply from: file("local-config.gradle")
buildscript {
ext.kotlin_version = "2.0.0"
repositories {
mavenLocal()
google()
mavenCentral()
}
}

rootProject.allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
}
Expand Down Expand Up @@ -78,6 +80,7 @@ android {
implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}")
implementation 'com.google.firebase:firebase-appcheck-debug'
implementation 'com.google.firebase:firebase-appcheck-playintegrity'
implementation 'com.google.firebase:firebase-appcheck-recaptcha:16.0.0-beta01'
implementation 'androidx.annotation:annotation:1.7.0'
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.FirebaseAppCheck
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory
import com.google.firebase.appcheck.playintegrity.PlayIntegrityAppCheckProviderFactory
import com.google.firebase.appcheck.recaptcha.RecaptchaAppCheckProviderFactory
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
import io.flutter.plugin.common.BinaryMessenger
Expand Down Expand Up @@ -62,6 +63,11 @@ class FirebaseAppCheckPlugin : FlutterFirebasePlugin, FlutterPlugin, FirebaseApp
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance())
}
"recaptcha" -> {
firebaseAppCheck.installAppCheckProviderFactory(
RecaptchaAppCheckProviderFactory.getInstance()
)
}
else -> {
firebaseAppCheck.installAppCheckProviderFactory(
PlayIntegrityAppCheckProviderFactory.getInstance())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2025, the Chromium project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Autogenerated from Pigeon (v25.3.2), do not edit directly.
// Autogenerated from Pigeon (v26.3.4), do not edit directly.
// See also: https://pub.dev/packages/pigeon
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")

Expand Down Expand Up @@ -40,12 +40,11 @@ private object GeneratedAndroidFirebaseAppCheckPigeonUtils {
* @property message The error message.
* @property details The error details. Must be a datatype supported by the api codec.
*/
class FlutterError(
val code: String,
override val message: String? = null,
val details: Any? = null
) : Throwable()

class FlutterError (
val code: String,
override val message: String? = null,
val details: Any? = null
) : RuntimeException()
private open class GeneratedAndroidFirebaseAppCheckPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return super.readValueOfType(type, buffer)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
allprojects {
repositories {
mavenLocal()
google()
mavenCentral()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ plugins {
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.9.22" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}

include ":app"
124 changes: 102 additions & 22 deletions packages/firebase_app_check/firebase_app_check/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,21 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
final appCheck = FirebaseAppCheck.instance;
String _message = '';
String _eventToken = 'not yet';
late final TextEditingController _webSiteKeyController;

@override
void initState() {
_webSiteKeyController = TextEditingController(text: kWebRecaptchaSiteKey);
appCheck.onTokenChange.listen(setEventToken);
super.initState();
}

@override
void dispose() {
_webSiteKeyController.dispose();
super.dispose();
}

void setMessage(String message) {
setState(() {
_message = message;
Expand All @@ -101,16 +109,25 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
Future<void> _activate({
AndroidAppCheckProvider? android,
AppleAppCheckProvider? apple,
String? webProviderType,
WindowsAppCheckProvider? windows,
}) async {
try {
dynamic providerWeb;
if (webProviderType == 'enterprise') {
providerWeb = ReCaptchaEnterpriseProvider(_webSiteKeyController.text);
} else if (webProviderType == 'v3') {
providerWeb = ReCaptchaV3Provider(_webSiteKeyController.text);
}

await appCheck.activate(
providerAndroid: android ?? const AndroidPlayIntegrityProvider(),
providerApple: apple ?? const AppleDeviceCheckProvider(),
providerWeb: ReCaptchaV3Provider(kWebRecaptchaSiteKey),
providerWeb: providerWeb,
providerWindows: windows ?? const WindowsDebugProvider(),
);
final providerName = windows?.runtimeType.toString() ??
webProviderType ??
apple?.runtimeType.toString() ??
android?.runtimeType.toString() ??
'default';
Expand All @@ -136,40 +153,103 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _activate(
android: const AndroidDebugProvider(),
apple: const AppleDebugProvider(),
windows: WindowsDebugProvider(
debugToken:
kWindowsDebugToken.isNotEmpty ? kWindowsDebugToken : null,
if (kIsWeb) ...[
ElevatedButton(
onPressed: () => _activate(
webProviderType: 'v3',
),
child: const Text('activate(Web reCAPTCHA v3)'),
),
child: const Text('activate(Debug)'),
),
ElevatedButton(
onPressed: () => _activate(
android: const AndroidPlayIntegrityProvider(),
apple: const AppleDeviceCheckProvider(),
const SizedBox(height: 8),
TextField(
controller: _webSiteKeyController,
decoration: const InputDecoration(
labelText: 'Web reCAPTCHA Site Key',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _activate(
webProviderType: 'enterprise',
),
child: const Text('activate(Web reCAPTCHA Enterprise)'),
),
],
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) ...[
ElevatedButton(
onPressed: () => _activate(
android: const AndroidDebugProvider(),
),
child: const Text('activate(Android Debug)'),
),
ElevatedButton(
onPressed: () => _activate(
android: const AndroidPlayIntegrityProvider(),
),
child: const Text('activate(Android Play Integrity)'),
),

const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _activate(
android: const AndroidReCaptchaProvider(),
),
child: const Text('activate(Android reCAPTCHA)'),
),
],
if (!kIsWeb &&
(defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.macOS)) ...[
ElevatedButton(
onPressed: () => _activate(
apple: const AppleDebugProvider(),
),
child: const Text('activate(Apple Debug)'),
),
ElevatedButton(
onPressed: () => _activate(
apple: const AppleDeviceCheckProvider(),
),
child: const Text('activate(Apple DeviceCheck)'),
),
child: const Text('activate(PlayIntegrity / DeviceCheck)'),
),
if (!kIsWeb)
ElevatedButton(
onPressed: () => _activate(
apple: const AppleAppAttestProvider(),
),
child: const Text('activate(AppAttest)'),
child: const Text('activate(Apple AppAttest)'),
),
if (!kIsWeb)
ElevatedButton(
onPressed: () => _activate(
apple: const AppleAppAttestWithDeviceCheckFallbackProvider(),
),
child: const Text(
'activate(AppAttest + DeviceCheck fallback)',
'activate(Apple AppAttest + DeviceCheck fallback)',
),
),
if (defaultTargetPlatform == TargetPlatform.iOS) ...[

const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _activate(
apple: const AppleReCaptchaProvider(),
),
child: const Text('activate(Apple reCAPTCHA)'),
),
],
],
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.windows) ...[
ElevatedButton(
onPressed: () => _activate(
windows: WindowsDebugProvider(
debugToken: kWindowsDebugToken.isNotEmpty
? kWindowsDebugToken
: null,
),
),
child: const Text('activate(Windows Debug)'),
),
],
const SizedBox(height: 16),
const Text(
'Actions',
Expand Down Expand Up @@ -226,15 +306,15 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
child: const Text('Test Firestore with App Check'),
),
const SizedBox(height: 20),
Text(
SelectableText(
_message,
style: const TextStyle(
color: Color.fromRGBO(47, 79, 79, 1),
fontSize: 16,
),
),
const SizedBox(height: 20),
Text(
SelectableText(
'Token from onTokenChange: $_eventToken',
style: const TextStyle(
color: Color.fromRGBO(128, 0, 128, 1),
Expand Down
Loading
Loading