2323import com .facebook .react .bridge .*;
2424import com .google .android .gms .tasks .Tasks ;
2525import com .google .firebase .FirebaseApp ;
26- import com .google .firebase .appcheck .AppCheckProviderFactory ;
2726import com .google .firebase .appcheck .FirebaseAppCheck ;
28- import com . google .firebase .appcheck . debug . DebugAppCheckProviderFactory ;
29- import com . google .firebase .appcheck . safetynet . SafetyNetAppCheckProviderFactory ;
27+ import io . invertase .firebase .common . ReactNativeFirebaseJSON ;
28+ import io . invertase .firebase .common . ReactNativeFirebaseMeta ;
3029import io .invertase .firebase .common .ReactNativeFirebaseModule ;
31- import java . lang . reflect .* ;
30+ import io . invertase . firebase . common . ReactNativeFirebasePreferences ;
3231
3332public class ReactNativeFirebaseAppCheckModule extends ReactNativeFirebaseModule {
3433 private static final String TAG = "AppCheck" ;
34+ private static final String LOGTAG = "RNFBAppCheck" ;
35+ private static final String KEY_APPCHECK_TOKEN_REFRESH_ENABLED = "app_check_token_auto_refresh" ;
36+ ReactNativeFirebaseAppCheckProviderFactory providerFactory =
37+ new ReactNativeFirebaseAppCheckProviderFactory ();
38+
39+ static boolean isAppCheckTokenRefreshEnabled () {
40+ boolean enabled ;
41+ ReactNativeFirebaseJSON json = ReactNativeFirebaseJSON .getSharedInstance ();
42+ ReactNativeFirebaseMeta meta = ReactNativeFirebaseMeta .getSharedInstance ();
43+ ReactNativeFirebasePreferences prefs = ReactNativeFirebasePreferences .getSharedInstance ();
44+
45+ if (prefs .contains (KEY_APPCHECK_TOKEN_REFRESH_ENABLED )) {
46+ enabled = prefs .getBooleanValue (KEY_APPCHECK_TOKEN_REFRESH_ENABLED , true );
47+ Log .d (LOGTAG , "isAppCheckCollectionEnabled via RNFBPreferences: " + enabled );
48+ } else if (json .contains (KEY_APPCHECK_TOKEN_REFRESH_ENABLED )) {
49+ enabled = json .getBooleanValue (KEY_APPCHECK_TOKEN_REFRESH_ENABLED , true );
50+ Log .d (LOGTAG , "isAppCheckCollectionEnabled via RNFBJSON: " + enabled );
51+ } else {
52+ enabled = meta .getBooleanValue (KEY_APPCHECK_TOKEN_REFRESH_ENABLED , true );
53+ Log .d (LOGTAG , "isAppCheckCollectionEnabled via RNFBMeta: " + enabled );
54+ }
55+
56+ if (BuildConfig .DEBUG ) {
57+ if (!json .getBooleanValue (KEY_APPCHECK_TOKEN_REFRESH_ENABLED , false )) {
58+ enabled = false ;
59+ }
60+ Log .d (
61+ LOGTAG ,
62+ "isAppCheckTokenRefreshEnabled after checking "
63+ + KEY_APPCHECK_TOKEN_REFRESH_ENABLED
64+ + ": "
65+ + enabled );
66+ }
67+
68+ Log .d (LOGTAG , "isAppCheckTokenRefreshEnabled final value: " + enabled );
69+ return enabled ;
70+ }
71+
72+ private boolean isAppDebuggable () throws Exception {
73+ boolean isDebuggable = false ;
74+ PackageManager pm = getContext ().getPackageManager ();
75+ if (pm != null ) {
76+ isDebuggable =
77+ (0
78+ != (pm .getApplicationInfo (getContext ().getPackageName (), 0 ).flags
79+ & ApplicationInfo .FLAG_DEBUGGABLE ));
80+ }
81+ Log .d (LOGTAG , "debuggable status? " + isDebuggable );
82+ return isDebuggable ;
83+ }
3584
3685 ReactNativeFirebaseAppCheckModule (ReactApplicationContext reactContext ) {
3786 super (reactContext , TAG );
87+
88+ // Our default token refresh config comes from config files, set it
89+ FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck .getInstance ();
90+ firebaseAppCheck .setTokenAutoRefreshEnabled (isAppCheckTokenRefreshEnabled ());
91+ }
92+
93+ @ ReactMethod
94+ public void configureProvider (
95+ String appName , String providerName , String debugToken , Promise promise ) {
96+ Log .d (
97+ LOGTAG ,
98+ "configureProvider - appName/providerName/debugToken: "
99+ + appName
100+ + "/"
101+ + providerName
102+ + (debugToken != null ? "/(not shown)" : "/null" ));
103+ try {
104+ providerFactory .configure (appName , providerName , debugToken );
105+ FirebaseAppCheck .getInstance (FirebaseApp .getInstance (appName ))
106+ .installAppCheckProviderFactory (providerFactory );
107+ promise .resolve (null );
108+ } catch (Exception e ) {
109+ rejectPromiseWithCodeAndMessage (promise , "unknown" , "internal-error" , e .getMessage ());
110+ }
38111 }
39112
40113 @ ReactMethod
41114 public void activate (
42115 String appName , String siteKeyProvider , boolean isTokenAutoRefreshEnabled , Promise promise ) {
43116 try {
44- FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck .getInstance ();
45- firebaseAppCheck .setTokenAutoRefreshEnabled (isTokenAutoRefreshEnabled );
46- boolean isDebuggable = false ;
47- PackageManager pm = getContext ().getPackageManager ();
48- if (pm != null ) {
49- isDebuggable =
50- (0
51- != (pm .getApplicationInfo (getContext ().getPackageName (), 0 ).flags
52- & ApplicationInfo .FLAG_DEBUGGABLE ));
53- }
54117
55- if (isDebuggable ) {
118+ FirebaseAppCheck firebaseAppCheck =
119+ FirebaseAppCheck .getInstance (FirebaseApp .getInstance (appName ));
120+ firebaseAppCheck .setTokenAutoRefreshEnabled (isTokenAutoRefreshEnabled );
56121
122+ // Configure our new proxy factory in a backwards-compatible way for old API
123+ if (isAppDebuggable ()) {
124+ Log .d (LOGTAG , "app is debuggable, configuring AppCheck for testing mode" );
57125 if (BuildConfig .FIREBASE_APP_CHECK_DEBUG_TOKEN != "null" ) {
58- // Get DebugAppCheckProviderFactory class
59- Class <DebugAppCheckProviderFactory > debugACFactoryClass =
60- DebugAppCheckProviderFactory .class ;
61-
62- // Get the (undocumented) constructor accepting a debug token as string
63- Class <?>[] argType = {String .class };
64- Constructor c = debugACFactoryClass .getDeclaredConstructor (argType );
65-
66- // Create a object containing the constructor arguments
67- // and initialize a new instance.
68- Object [] cArgs = {BuildConfig .FIREBASE_APP_CHECK_DEBUG_TOKEN };
69- firebaseAppCheck .installAppCheckProviderFactory (
70- (AppCheckProviderFactory ) c .newInstance (cArgs ));
126+ Log .d (LOGTAG , "debug app check token found in BuildConfig. Installing known token." );
127+ providerFactory .configure (appName , "debug" , BuildConfig .FIREBASE_APP_CHECK_DEBUG_TOKEN );
71128 } else {
72- firebaseAppCheck .installAppCheckProviderFactory (
73- DebugAppCheckProviderFactory .getInstance ());
129+ Log .d (
130+ LOGTAG ,
131+ "no debug app check token found in BuildConfig. Check Log for dynamic test token to"
132+ + " configure in console." );
133+ providerFactory .configure (appName , "debug" , null );
74134 }
75-
76135 } else {
77- firebaseAppCheck .installAppCheckProviderFactory (
78- SafetyNetAppCheckProviderFactory .getInstance ());
136+ providerFactory .configure (appName , "safetyNet" , null );
79137 }
138+
139+ FirebaseAppCheck .getInstance (FirebaseApp .getInstance (appName ))
140+ .installAppCheckProviderFactory (providerFactory );
141+ promise .resolve (null );
80142 } catch (Exception e ) {
81- rejectPromiseWithCodeAndMessage (promise , "unknown" , "internal-error" , "unimplemented" );
82- return ;
143+ rejectPromiseWithCodeAndMessage (promise , "unknown" , "internal-error" , e .getMessage ());
83144 }
84- promise .resolve (null );
85145 }
86146
87147 @ ReactMethod
@@ -92,6 +152,7 @@ public void setTokenAutoRefreshEnabled(String appName, boolean isTokenAutoRefres
92152
93153 @ ReactMethod
94154 public void getToken (String appName , boolean forceRefresh , Promise promise ) {
155+ Log .d (LOGTAG , "getToken appName/forceRefresh: " + appName + "/" + forceRefresh );
95156 FirebaseApp firebaseApp = FirebaseApp .getInstance (appName );
96157 Tasks .call (
97158 getExecutor (),
@@ -108,7 +169,7 @@ public void getToken(String appName, boolean forceRefresh, Promise promise) {
108169 promise .resolve (tokenResultMap );
109170 } else {
110171 Log .e (
111- TAG ,
172+ LOGTAG ,
112173 "RNFB: Unknown error while fetching AppCheck token "
113174 + task .getException ().getMessage ());
114175 rejectPromiseWithCodeAndMessage (
0 commit comments