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 @@ -80,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-recaptchaenterprise: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 @@ -9,6 +9,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.recaptchaenterprise.RecaptchaEnterpriseAppCheckProviderFactory
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 @@ -55,6 +56,7 @@ class FirebaseAppCheckPlugin :
androidProvider: String?,
appleProvider: String?,
debugToken: String?,
recaptchaEnterpriseSiteKey: String?,
callback: (Result<Unit>) -> Unit
) {
try {
Expand All @@ -66,6 +68,16 @@ class FirebaseAppCheckPlugin :
DebugAppCheckProviderFactory.getInstance()
)
}
"recaptchaEnterprise" -> {
if (recaptchaEnterpriseSiteKey != null) {
firebaseAppCheck.installAppCheckProviderFactory(
RecaptchaEnterpriseAppCheckProviderFactory.getInstance(recaptchaEnterpriseSiteKey)
)
} else {
callback(Result.failure(FlutterError("invalid-argument", "Site key is required for reCAPTCHA Enterprise", null)))
return
}
}
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 @@ -49,7 +49,7 @@ class FlutterError (
val code: String,
override val message: String? = null,
val details: Any? = null
) : Throwable()
) : RuntimeException()
private open class GeneratedAndroidFirebaseAppCheckPigeonCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
return super.readValueOfType(type, buffer)
Expand All @@ -62,7 +62,7 @@ private open class GeneratedAndroidFirebaseAppCheckPigeonCodec : StandardMessage

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface FirebaseAppCheckHostApi {
fun activate(appName: String, androidProvider: String?, appleProvider: String?, debugToken: String?, callback: (Result<Unit>) -> Unit)
fun activate(appName: String, androidProvider: String?, appleProvider: String?, debugToken: String?, recaptchaEnterpriseSiteKey: String?, callback: (Result<Unit>) -> Unit)
fun getToken(appName: String, forceRefresh: Boolean, callback: (Result<String?>) -> Unit)
fun setTokenAutoRefreshEnabled(appName: String, isTokenAutoRefreshEnabled: Boolean, callback: (Result<Unit>) -> Unit)
fun registerTokenListener(appName: String, callback: (Result<String>) -> Unit)
Expand All @@ -86,7 +86,8 @@ interface FirebaseAppCheckHostApi {
val androidProviderArg = args[1] as String?
val appleProviderArg = args[2] as String?
val debugTokenArg = args[3] as String?
api.activate(appNameArg, androidProviderArg, appleProviderArg, debugTokenArg) { result: Result<Unit> ->
val recaptchaEnterpriseSiteKeyArg = args[4] as String?
api.activate(appNameArg, androidProviderArg, appleProviderArg, debugTokenArg, recaptchaEnterpriseSiteKeyArg) { result: Result<Unit> ->
val error = result.exceptionOrNull()
if (error != null) {
reply.reply(GeneratedAndroidFirebaseAppCheckPigeonUtils.wrapError(error))
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"
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 _siteKeyController;

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

@override
void dispose() {
_siteKeyController.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(_siteKeyController.text);
} else if (webProviderType == 'v3') {
providerWeb = ReCaptchaV3Provider(_siteKeyController.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 Down Expand Up @@ -170,6 +187,27 @@ class _FirebaseAppCheck extends State<FirebaseAppCheckExample> {
'activate(AppAttest + DeviceCheck fallback)',
),
),
const SizedBox(height: 8),
TextField(
controller: _siteKeyController,
decoration: const InputDecoration(
labelText: 'reCAPTCHA Site Key',
border: OutlineInputBorder(),
),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _activate(
android: AndroidReCaptchaEnterpriseProvider(siteKey: _siteKeyController.text),
),
child: const Text('activate(Android reCAPTCHA Enterprise)'),
),
ElevatedButton(
onPressed: () => _activate(
webProviderType: 'enterprise',
),
child: const Text('activate(Web reCAPTCHA Enterprise)'),
),
const SizedBox(height: 16),
const Text(
'Actions',
Expand Down
Loading
Loading