Android Question Firebase Auth - With Resumable Sub

Gentry

Member
Licensed User
Longtime 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
Longtime 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.
 
Upvote 0

toby

Well-Known Member
Licensed User
Longtime 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.
 
Upvote 0

Gentry

Member
Licensed User
Longtime 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...
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime 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 :)]
 
Upvote 0

Gentry

Member
Licensed User
Longtime 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.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime 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
 
Upvote 0
Top