Android Question Firebase Auth - With Resumable Sub

Gentry

Member
Licensed User
I am trying to achieve an elegant Firebase authentication module that transparently re-authenticates and renews the Firebase Token after the initial authentication. If the re-authentication or the token renewal fails, then the module should display the login button and allow a fresh login.

Here is my module code:
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals

End Sub

Sub Globals
     Private lblName As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    'Activity.LoadLayout("Layout1")
    If FirstTime Then
        Starter.fAuth.Initialize("fbAuth")
        Wait For fbAuth_SignedIn (User As FirebaseUser)
        Log("fbAuth_SignedIn - User = "&User)
        Starter.fAuth.GetUserTokenId(User,False)
        Wait For fbAuth_TokenAvailable (User As FirebaseUser, Success As Boolean, TokenId As String)
        Log("fbAuth_TokenAvailable - Token = "&TokenId)              
    End If

End Sub

Sub btnSignIn_Click
   Starter.fAuth.SignInWithGoogle
End Sub

Sub btnSignOut_Click
   Starter.fAuth.SignOutFromGoogle
   lblName.Text = "Goodbye!"
End Sub

Sub fbAuth_SignedIn (User As FirebaseUser)
'    Starter.fAuth.GetUserTokenId(User,False)
    Starter.fbuser = User
    Log("SignedIn: " & User.DisplayName)
    Return
End Sub

Sub fbAuth_TokenAvailable (User As FirebaseUser, Success As Boolean, TokenId As String)
    If Success Then
        Dim fbexpiretime As Period
        fbexpiretime.Minutes = 55
        Starter.fbtokenexpires = DateUtils.AddPeriod(DateTime.Now, fbexpiretime)
        Log("FirebaseJWT "&TokenId)
        Starter.fbtoken = TokenId
        Activity.Finish
    Else
        Log("No Token :(")
        Activity.LoadLayout("fbAuth")
    End If
    Return
End Sub

Sub Activity_Resume
   If Starter.fAuth.CurrentUser.IsInitialized Then
            fbAuth_SignedIn(Starter.fAuth.CurrentUser)
   Else
         Activity.LoadLayout("fbAuth")
   End If
 
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub btnContinue_Click
    If Starter.fbtoken <> "" Then
        StartActivity(Main)
    End If
End Sub

Thanks for taking a look, I imagine this function would be helpful to other Firebase users.
Gentry
 

LucaMs

Expert
Licensed User
I was trying (few days ago) to create an Activity "standard" to handle user registration-authentication (mixing Firebase-Google with custom stuff in the same Activity).

These are just my first battles against FirebaseAuth :D
The first thing I noticed is that the SignedIn event will only start after the Activity_Resume is executed. Furthermore, this event will read local data if you are not connected to Internet.
 

toby

Active Member
Licensed User
When running the FirebaseAuth example, my logs show that SignInWithGoogle() returns results before Activity_Resume event, maybe that's why SignedIn event was never raised during my tests so far. How to make sure SignedIn event, if any, is raised after Activity_Resume, not before?


Thanks

my unfiltered debug log:
Validating map...
*** Service (starter) Create ***
** Service (starter) Start **
Initialized EGL, version 1.4
Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
Enabling debug mode 0
** Activity (main) Create, isFirst = true **
FirebaseAuth initialized
** Activity (main) Resume **
onAuthStateChanged: com.google.android.gms.internal.lr@123390af
SignInWithGoogle called
** Activity (main) Pause, UserClosed = false **
SetAppTypeFace- try to flip, app = b4a.firebase2
Typeface getFontPathFlipFont - systemFont = default#default
sending message to waiting queue (OnActivityResult)
running waiting messages (1)
SignInWithGoogle.ResultArrived
ResultArrived Success
** Activity (main) Resume **
** Activity (main) Pause, UserClosed = false **
beginBatchEdit on inactive InputConnection
endBatchEdit on inactive InputConnection
Local module descriptor class for com.google.firebase.auth not found.
 

Gentry

Member
Licensed User
I think I misunderstood what the fauth.initialize does. I am having better success moving the Wait For Stack from Activity_Create down to Activity_Resume, like this:

B4X:
Sub Activity_Resume
   If Starter.fAuth.CurrentUser.IsInitialized Then
            fbAuth_SignedIn(Starter.fAuth.CurrentUser)
        Wait For fbAuth_SignedIn (User As FirebaseUser)
        uh.tLog("fbAuth_SignedIn - User = "&User)
        Wait For fbAuth_TokenAvailable (User As FirebaseUser, Success As Boolean, TokenId As String)
        uh.tLog("fbAuth_TokenAvailable - Token = "&TokenId)       

   Else
         Activity.LoadLayout("fbAuth")
   End If
  
End Sub
And removed the Activity.Finish in the TokenAvailable(). that seemed to be killing my entire app.

More testing though...
 

LucaMs

Expert
Licensed User
When running the FirebaseAuth example, my logs show that SignInWithGoogle() returns results before Activity_Resume event
In that example, SignInWithGoogle is called by a button event routine, then Activity_Resume is alredy raised.

I think that the auth (in that example) initialization sends the request (if online!!!) and then the SigneId event will be raised only after the Activity_Resume.

[now I have to read your new code :)]
 

Gentry

Member
Licensed User
Right, my goal is to enhance the original example, so that it bypasses the screen/view that displays the Login button, and, if you are already authenticated (in cache) that it renews the token and returns to the main program.
 

LucaMs

Expert
Licensed User
Sub Activity_Resume
If Starter.fAuth.CurrentUser.IsInitialized Then
This line will be executed before the SignedIn event, I think; also, it could return True even without an internet connection actived (I'm not sure, I too have to test)
 

LucaMs

Expert
Licensed User
Right, my goal is to enhance the original example, so that it bypasses the screen/view that displays the Login button, and, if you are already authenticated (in cache) that it renews the token and returns to the main program.
I'm thinking to a dedicated Activity, which should allow custom registration-login and firebase-google stuff.

I was trying setting a state, based on local data saved. Currently, I have not resumed working on it. Maybe after a good coffee I will do it :D
 
Top