@@ -5,7 +5,6 @@ import android.content.Context
55import android.content.Intent
66import android.util.Log
77import com.clerk.api.Clerk
8- import com.clerk.api.network.serialization.ClerkResult
98import com.facebook.react.bridge.ActivityEventListener
109import com.facebook.react.bridge.Promise
1110import com.facebook.react.bridge.ReactApplicationContext
@@ -68,63 +67,41 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
6867 try {
6968 publishableKey = pubKey
7069
71- if ( ! Clerk .isInitialized.value) {
72- // First-time initialization — write the bearer token to SharedPreferences
73- // before initializing so the SDK boots with the correct client.
74- if ( ! bearerToken.isNullOrEmpty()) {
75- reactApplicationContext.getSharedPreferences( " clerk_preferences " , Context . MODE_PRIVATE )
76- .edit( )
77- .putString( " DEVICE_TOKEN " , bearerToken )
78- . apply ( )
79- }
70+ // If the JS SDK has a bearer token, write it to the native SDK's
71+ // SharedPreferences so both SDKs share the same Clerk API client.
72+ if ( ! bearerToken.isNullOrEmpty()) {
73+ reactApplicationContext.getSharedPreferences( " clerk_preferences " , Context . MODE_PRIVATE )
74+ .edit( )
75+ .putString( " DEVICE_TOKEN " , bearerToken )
76+ . apply ( )
77+ debugLog( TAG , " configure - wrote JS bearer token to native SharedPreferences " )
78+ }
8079
81- Clerk .initialize(reactApplicationContext, pubKey)
82-
83- // Wait for initialization to complete with timeout
84- try {
85- withTimeout(10_000L ) {
86- Clerk .isInitialized.first { it }
87- }
88- } catch (e: TimeoutCancellationException ) {
89- val initError = Clerk .initializationError.value
90- val message = if (initError != null ) {
91- " Clerk initialization timed out: ${initError.message} "
92- } else {
93- " Clerk initialization timed out after 10 seconds"
94- }
95- promise.reject(" E_TIMEOUT" , message)
96- return @launch
97- }
80+ Clerk .initialize(reactApplicationContext, pubKey)
9881
99- // Check for initialization errors
100- val error = Clerk .initializationError.value
101- if (error != null ) {
102- promise.reject(" E_INIT_FAILED" , " Failed to initialize Clerk SDK: ${error.message} " )
82+ // Wait for initialization to complete with timeout
83+ try {
84+ withTimeout(10_000L ) {
85+ Clerk .isInitialized.first { it }
86+ }
87+ } catch (e: TimeoutCancellationException ) {
88+ val initError = Clerk .initializationError.value
89+ val message = if (initError != null ) {
90+ " Clerk initialization timed out: ${initError.message} "
10391 } else {
104- promise.resolve( null )
92+ " Clerk initialization timed out after 10 seconds "
10593 }
94+ promise.reject(" E_TIMEOUT" , message)
10695 return @launch
10796 }
10897
109- // Already initialized — use the public SDK API to update
110- // the device token and trigger a client/environment refresh.
111- if (! bearerToken.isNullOrEmpty()) {
112- val result = Clerk .updateDeviceToken(bearerToken)
113- if (result is ClerkResult .Failure ) {
114- debugLog(TAG , " configure - updateDeviceToken failed: ${result.error} " )
115- }
116-
117- // Wait for session to appear with the new token (up to 5s)
118- try {
119- withTimeout(5_000L ) {
120- Clerk .sessionFlow.first { it != null }
121- }
122- } catch (_: TimeoutCancellationException ) {
123- debugLog(TAG , " configure - session did not appear after token update" )
124- }
98+ // Check for initialization errors
99+ val error = Clerk .initializationError.value
100+ if (error != null ) {
101+ promise.reject(" E_INIT_FAILED" , " Failed to initialize Clerk SDK: ${error.message} " )
102+ } else {
103+ promise.resolve(null )
125104 }
126-
127- promise.resolve(null )
128105 } catch (e: Exception ) {
129106 promise.reject(" E_INIT_FAILED" , " Failed to initialize Clerk SDK: ${e.message} " , e)
130107 }
@@ -197,15 +174,15 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
197174 @ReactMethod
198175 override fun getSession (promise : Promise ) {
199176 if (! Clerk .isInitialized.value) {
200- // Return null when not initialized (matches iOS behavior)
201- // so callers can proceed to call configure() with a bearer token.
202- promise.resolve(null )
177+ promise.reject(" E_NOT_INITIALIZED" , " Clerk SDK is not initialized. Call configure() first." )
203178 return
204179 }
205180
206181 val session = Clerk .session
207182 val user = Clerk .user
208183
184+ debugLog(TAG , " getSession - hasSession: ${session != null } , hasUser: ${user != null } " )
185+
209186 val result = WritableNativeMap ()
210187
211188 session?.let {
@@ -240,6 +217,7 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
240217 try {
241218 val prefs = reactApplicationContext.getSharedPreferences(" clerk_preferences" , Context .MODE_PRIVATE )
242219 val deviceToken = prefs.getString(" DEVICE_TOKEN" , null )
220+ debugLog(TAG , " getClientToken - deviceToken: ${if (deviceToken != null ) " found" else " null" } " )
243221 promise.resolve(deviceToken)
244222 } catch (e: Exception ) {
245223 debugLog(TAG , " getClientToken failed: ${e.message} " )
@@ -252,8 +230,7 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
252230 @ReactMethod
253231 override fun signOut (promise : Promise ) {
254232 if (! Clerk .isInitialized.value) {
255- // Resolve gracefully when not initialized (matches iOS behavior)
256- promise.resolve(null )
233+ promise.reject(" E_NOT_INITIALIZED" , " Clerk SDK is not initialized. Call configure() first." )
257234 return
258235 }
259236
@@ -281,13 +258,17 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
281258 }
282259
283260 private fun handleAuthResult (resultCode : Int , data : Intent ? ) {
261+ debugLog(TAG , " handleAuthResult - resultCode: $resultCode " )
262+
284263 val promise = pendingAuthPromise ? : return
285264 pendingAuthPromise = null
286265
287266 if (resultCode == Activity .RESULT_OK ) {
288267 val session = Clerk .session
289268 val user = Clerk .user
290269
270+ debugLog(TAG , " handleAuthResult - hasSession: ${session != null } , hasUser: ${user != null } " )
271+
291272 val result = WritableNativeMap ()
292273
293274 // Top-level sessionId for JS SDK compatibility (matches iOS response format)
@@ -315,6 +296,7 @@ class ClerkExpoModule(reactContext: ReactApplicationContext) :
315296
316297 promise.resolve(result)
317298 } else {
299+ debugLog(TAG , " handleAuthResult - user cancelled" )
318300 val result = WritableNativeMap ()
319301 result.putBoolean(" cancelled" , true )
320302 promise.resolve(result)
0 commit comments