14
14
15
15
// For Sign in with Facebook
16
16
import FBSDKLoginKit
17
- import FirebaseAuth
17
+ @ testable import FirebaseAuth
18
18
19
19
// [START auth_import]
20
20
import FirebaseCore
@@ -33,6 +33,8 @@ private let kFacebookAppID = "ENTER APP ID HERE"
33
33
34
34
class AuthViewController : UIViewController , DataSourceProviderDelegate {
35
35
var dataSourceProvider : DataSourceProvider < AuthMenu > !
36
+ var authStateDidChangeListeners : [ AuthStateDidChangeListenerHandle ] = [ ]
37
+ var IDTokenDidChangeListeners : [ IDTokenDidChangeListenerHandle ] = [ ]
36
38
37
39
override func loadView( ) {
38
40
view = UITableView ( frame: . zero, style: . insetGrouped)
@@ -95,6 +97,30 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate {
95
97
96
98
case . customAuthDomain:
97
99
performCustomAuthDomainFlow ( )
100
+
101
+ case . getToken:
102
+ getUserTokenResult ( force: false )
103
+
104
+ case . getTokenForceRefresh:
105
+ getUserTokenResult ( force: true )
106
+
107
+ case . addAuthStateChangeListener:
108
+ addAuthStateListener ( )
109
+
110
+ case . removeLastAuthStateChangeListener:
111
+ removeAuthStateListener ( )
112
+
113
+ case . addIdTokenChangeListener:
114
+ addIDTokenListener ( )
115
+
116
+ case . removeLastIdTokenChangeListener:
117
+ removeIDTokenListener ( )
118
+
119
+ case . verifyClient:
120
+ verifyClient ( )
121
+
122
+ case . deleteApp:
123
+ deleteApp ( )
98
124
}
99
125
}
100
126
@@ -316,6 +342,142 @@ class AuthViewController: UIViewController, DataSourceProviderDelegate {
316
342
present ( prompt, animated: true )
317
343
}
318
344
345
+ private func getUserTokenResult( force: Bool ) {
346
+ guard let currentUser = Auth . auth ( ) . currentUser else {
347
+ print ( " Error: No user logged in " )
348
+ return
349
+ }
350
+
351
+ currentUser. getIDTokenResult ( forcingRefresh: force, completion: { tokenResult, error in
352
+ if error != nil {
353
+ print ( " Error: Error refreshing token " )
354
+ return // Handle error case, returning early
355
+ }
356
+
357
+ if let tokenResult = tokenResult, let claims = tokenResult. claims as? [ String : Any ] {
358
+ var message = " Token refresh succeeded \n \n "
359
+ for (key, value) in claims {
360
+ message += " \( key) : \( value) \n "
361
+ }
362
+ self . displayInfo ( title: " Info " , message: message, style: . alert)
363
+ } else {
364
+ print ( " Error: Unable to access claims. " )
365
+ }
366
+ } )
367
+ }
368
+
369
+ private func addAuthStateListener( ) {
370
+ weak var weakSelf = self
371
+ let index = authStateDidChangeListeners. count
372
+ print ( " Auth State Did Change Listener # \( index) was added. " )
373
+ let handle = Auth . auth ( ) . addStateDidChangeListener { [ weak weakSelf] auth, user in
374
+ guard weakSelf != nil else { return }
375
+ print ( " Auth State Did Change Listener # \( index) was invoked on user ' \( user? . uid ?? " nil " ) ' " )
376
+ }
377
+ authStateDidChangeListeners. append ( handle)
378
+ }
379
+
380
+ private func removeAuthStateListener( ) {
381
+ guard !authStateDidChangeListeners. isEmpty else {
382
+ print ( " No remaining Auth State Did Change Listeners. " )
383
+ return
384
+ }
385
+ let index = authStateDidChangeListeners. count - 1
386
+ let handle = authStateDidChangeListeners. last!
387
+ Auth . auth ( ) . removeStateDidChangeListener ( handle)
388
+ authStateDidChangeListeners. removeLast ( )
389
+ print ( " Auth State Did Change Listener # \( index) was removed. " )
390
+ }
391
+
392
+ private func addIDTokenListener( ) {
393
+ weak var weakSelf = self
394
+ let index = IDTokenDidChangeListeners . count
395
+ print ( " ID Token Did Change Listener # \( index) was added. " )
396
+ let handle = Auth . auth ( ) . addIDTokenDidChangeListener { [ weak weakSelf] auth, user in
397
+ guard weakSelf != nil else { return }
398
+ print ( " ID Token Did Change Listener # \( index) was invoked on user ' \( user? . uid ?? " " ) '. " )
399
+ }
400
+ IDTokenDidChangeListeners . append ( handle)
401
+ }
402
+
403
+ func removeIDTokenListener( ) {
404
+ guard !IDTokenDidChangeListeners. isEmpty else {
405
+ print ( " No remaining ID Token Did Change Listeners. " )
406
+ return
407
+ }
408
+ let index = IDTokenDidChangeListeners . count - 1
409
+ let handle = IDTokenDidChangeListeners . last!
410
+ Auth . auth ( ) . removeIDTokenDidChangeListener ( handle)
411
+ IDTokenDidChangeListeners . removeLast ( )
412
+ print ( " ID Token Did Change Listener # \( index) was removed. " )
413
+ }
414
+
415
+ func verifyClient( ) {
416
+ AppManager . shared. auth ( ) . tokenManager. getTokenInternal { token, error in
417
+ if token == nil {
418
+ print ( " Verify iOS Client failed. " )
419
+ return
420
+ }
421
+ let request = VerifyClientRequest (
422
+ withAppToken: token? . string,
423
+ isSandbox: token? . type == . sandbox,
424
+ requestConfiguration: AppManager . shared. auth ( ) . requestConfiguration
425
+ )
426
+
427
+ Task {
428
+ do {
429
+ let verifyResponse = try await AuthBackend . call ( with: request)
430
+
431
+ guard let receipt = verifyResponse. receipt,
432
+ let timeoutDate = verifyResponse. suggestedTimeOutDate else {
433
+ print ( " Internal Auth Error: invalid VerifyClientResponse. " )
434
+ return
435
+ }
436
+
437
+ let timeout = timeoutDate. timeIntervalSinceNow
438
+ do {
439
+ let credential = await AppManager . shared. auth ( ) . appCredentialManager
440
+ . didStartVerification (
441
+ withReceipt: receipt,
442
+ timeout: timeout
443
+ )
444
+
445
+ guard credential. secret != nil else {
446
+ print ( " Failed to receive remote notification to verify App ID. " )
447
+ return
448
+ }
449
+
450
+ let testPhoneNumber = " +16509964692 "
451
+ let request = SendVerificationCodeRequest (
452
+ phoneNumber: testPhoneNumber,
453
+ codeIdentity: CodeIdentity . credential ( credential) ,
454
+ requestConfiguration: AppManager . shared. auth ( ) . requestConfiguration
455
+ )
456
+
457
+ do {
458
+ _ = try await AuthBackend . call ( with: request)
459
+ print ( " Verify iOS client succeeded " )
460
+ } catch {
461
+ print ( " Verify iOS Client failed: \( error. localizedDescription) " )
462
+ }
463
+ }
464
+ } catch {
465
+ print ( " Verify iOS Client failed: \( error. localizedDescription) " )
466
+ }
467
+ }
468
+ }
469
+ }
470
+
471
+ func deleteApp( ) {
472
+ AppManager . shared. app. delete { success in
473
+ if success {
474
+ print ( " App deleted successfully. " )
475
+ } else {
476
+ print ( " Failed to delete app. " )
477
+ }
478
+ }
479
+ }
480
+
319
481
// MARK: - Private Helpers
320
482
321
483
private func configureDataSourceProvider( ) {
0 commit comments