B4J Question firebase verification for signed in users

enrfortin

Member
Licensed User
I tried to follow the following example for Google authentication


but I get the same error that I have seen in the forum in some posts without any answer.


error:
Waiting for debugger to connect...
Program started.
2023-08-09 18:25:05.354:INFO :cmvl.MLog:MLog-Init-Reporter: MLog clients using slf4j logging.
2023-08-09 18:25:06.022:INFO :cmvc.C3P0Registry:main: Initializing c3p0-0.9.5.2 [built 08-December-2015 22:06:04 -0800; debug? true; trace: 10]
2023-08-09 18:25:06.497:INFO :oejs.Server:main: jetty-11.0.9; built: 2022-03-30T17:44:47.085Z; git: 243a48a658a183130a8c8de353178d154ca04f04; jvm 11.0.1+13
2023-08-09 18:25:06.684:INFO :oejss.DefaultSessionIdManager:main: Session workerName=node0
2023-08-09 18:25:06.707:INFO :oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@3a5ecce3{/,file:///C:/Users/MacBookPro/Desktop/Sistema%20Prestamos%20Cloud/Prestamos%20Cloud/Objects/www/,AVAILABLE}
2023-08-09 18:25:06.760:INFO :oejs.RequestLogWriter:main: Opened C:\Users\MacBookPro\Desktop\Sistema Prestamos Cloud\Prestamos Cloud\Objects\logs\b4j-2023_08_10.request.log
2023-08-09 18:25:06.781:INFO :oejs.AbstractConnector:main: Started ServerConnector@782859e{HTTP/1.1, (http/1.1)}{0.0.0.0:51042}
2023-08-09 18:25:06.828:INFO :oejus.SslContextFactory:main: x509=X509@30b19518(1,h=[localhost],a=[/127.0.0.1],w=[]) for Server@62e20a76[provider=null,keyStore=file:///C:/Users/MacBookPro/Desktop/Sistema%20Prestamos%20Cloud/Prestamos%20Cloud/Objects/localhost.jks,trustStore=null]
2023-08-09 18:25:07.007:INFO :oejs.AbstractConnector:main: Started ServerConnector@69ee81fc{SSL, (ssl, http/1.1)}{0.0.0.0:51044}
2023-08-09 18:25:07.012:INFO :oejs.Server:main: Started Server@1f81aa00{STARTING}[11.0.9,sto=0] @3410ms
Emulated network latency: 100ms
java.lang.IllegalArgumentException
    at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:111)
    at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:37)
    at com.google.api.client.json.webtoken.JsonWebSignature$Parser.parse(JsonWebSignature.java:599)
    at com.google.firebase.auth.FirebaseToken.parse(FirebaseToken.java:81)
    at com.google.firebase.auth.FirebaseAuth$1.call(FirebaseAuth.java:143)
    at com.google.firebase.auth.FirebaseAuth$1.call(FirebaseAuth.java:140)
    at com.google.firebase.tasks.Tasks$1.run(Tasks.java:63)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Token verification failed

I guess my real question is where did I get the VerifyToken("eyJhbGciOiJSUzI1NiIsImtpZCI6IjE1ZWE4ZDBkMDI1ZDExNGFiNzU0MmQ2OT...")

I thought I could create it by sending the google email and password parameters but I can't find any function that allows me to do it.

I am not very good with this I always rely on the guides I do not know if this library is still functional.

i all ready have de json file from the image
1691627800327.png

this is my main code:

main code:
#Region Project Attributes
    #CommandLineArgs:
    #MergeLibraries: True
    #AdditionalJar: mysql-connector-j-8.1.0.jar
#End Region

Sub Process_Globals
    Public srvr As Server
    Public pool As ConnectionPool
    Private fs As FirebaseServer
End Sub

Sub AppStart (Args() As String)
    pool.Initialize("com.mysql.jdbc.Driver","jdbc:mysql://127.0.0.1/sistemacloud?Encoding=utf8","user","pass")   
    srvr.Initialize("srvr")
    srvr.Port = 51042
    srvr.StaticFilesFolder = File.Combine(File.DirApp, "www")
    srvr.AddWebSocket("/login", "login")
    srvr.AddWebSocket("/Dashboard", "Dashboard")
    srvr.AddFilter("/b4j_ws.js", "SessionCreator", False)
    ConfigureSSL(51044)
    srvr.Start
    fs.Initialize("fs", File.OpenInput(File.DirAssets, "sistema-prestamos-cloud-firebase-adminsdk-j5vcp-6e3a8c3bed.json"))
    'fs.VerifyToken("AIzaSyBElE2gscykbUfTYKwQ7Omt5q-2cF18odc")
    StartMessageLoop
    'open browser and navigate to: http://127.0.0.1:51042/
        
End Sub


'Sub fs_TokenVerified (TokenId As String, Success As Boolean, Token As FirebaseToken)
'    If Success Then
'        Log(Token.DisplayName)
'        Log(Token.Email)
'        Log(Token.Uid)
'    End If
'End Sub


Sub verifytoken(token As String)
    fs.VerifyToken(token)
End Sub

Sub fs_TokenVerified (TokenId As String, Success As Boolean, Token As FirebaseToken)
   If Success Then
      Log("User verified:")
      Log("Display Name: " & Token.DisplayName)
      Log("Email: " & Token.Email)
      Log("User ID: " & Token.Uid)
   Else
      Log("Token verification failed")
   End If
End Sub

Private Sub ConfigureSSL (SslPort As Int)
    'example of SSL connector configuration
    Dim ssl As SslConfiguration
    ssl.Initialize
    ssl.SetKeyStorePath(File.DirApp, "localhost.jks") 'path to keystore file
    ssl.KeyStorePassword = "xxxxxx"
    ssl.KeyManagerPassword = "xxxxxxx"
    srvr.SetSslConfiguration(ssl, SslPort)
    'add filter to redirect all traffic from http to https (optional)
    srvr.AddFilter("/*", "HttpsFilter", False)
End Sub

public Sub ValidarUsuario(ws As WebSocket, lblusernamemain As JQueryElement)
    Try
        If ws.Session.GetAttribute("id_usuario") = Null Or 0 = ws.Session.GetAttribute("id_usuario") Then           
            ws.Eval("document.location.replace('login.html')",Null)
        Else
            lblusernamemain.SetHtml(ws.Session.GetAttribute("nombre"))
        End If       
    Catch
        Log(LastException)
    End Try
End Sub

thanks for your help
 

enrfortin

Member
Licensed User
I think this is a misunderstanding I've had what I want to do is just to show a login popup window to get the: email name and uid of the user I thought this could help me like firebaseAuth does in b4i or b4a but I understood that it is only to validate that data so I had no idea where to get the JWT token I will read other documentation and guides to find what I need, thank you very much for your time in responding to this post if you have a link to a post that can help me with what I need I would appreciate it, greetings.
 
Upvote 0

aeric

Expert
Licensed User
Longtime User
I think this is a misunderstanding I've had what I want to do is just to show a login popup window to get the: email name and uid of the user I thought this could help me like firebaseAuth does in b4i or b4a but I understood that it is only to validate that data so I had no idea where to get the JWT token I will read other documentation and guides to find what I need, thank you very much for your time in responding to this post if you have a link to a post that can help me with what I need I would appreciate it, greetings.
I guess you are looking for this
 
Upvote 0

enrfortin

Member
Licensed User
ok, the question I had was not so difficult to answer I leave the steps in case some newbie like me, has the same problem.

this is how I got it if anyone else needs to know about this


B4X:
Sub Class_Globals
    Private google_login As JQueryElement 'make sure this is the id of the button'
    Private facebook_login As JQueryElement 'make sure this is the id of the button'
    Private jscript As String
End Sub

Public Sub Initialize
    jscript=$"
var firebaseConfig = {
apiKey: "...",
authDomain: "...",
projectId: "...",
appId: "..."
};
firebase.initializeApp(firebaseConfig);

    "$
End Sub

Private Sub WebSocket_Connected (WebSocket1 As WebSocket)
    ws = WebSocket1 
    ws.Eval(jscript,Null)
End Sub

Sub google_login_Click (Params As Map)
    Log("btn google precionado")
 
    ws.Eval("setTimeout(function() { signInWithGoogle(); }, 100);", Null)
 
End Sub

Sub facebook_login_Click (Params As Map)

    Log("btn facebook precionado")
 
    ws.Eval("setTimeout(function() { signInWithFacebook(); }, 100);", Null)
End Sub


Sub event_register(variable As Map)
    Log("llamaron al event register")
    Log(variable.Get("tk"))
    Dim token As String = variable.Get("tk")
    Main.fs.VerifyToken(token)
End Sub


Sub fs_TokenVerified (TokenId As String, Success As Boolean, Token As FirebaseToken)
    If Success Then
        Log(Token.DisplayName)
        Log(Token.Email)
        Log(Token.Uid)
    End If
End Sub


'in the main tab'
Sub Process_Globals
    Public fs As FirebaseServer
End Sub



Sub AppStart (Args() As String)
    fs.Initialize("fs", File.OpenInput(File.DirAssets,"file.json")) 'put this in the file tab      
End Sub
-------------------------

'In the html put these scripts'
<script>

function signInWithGoogle() {
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider)
.then((result) => {
firebase.auth().currentUser.getIdToken(true).then(function(idToken) {
    var token = idToken;
    b4j_raiseEvent('event_register', {tk:token});
}).catch(function(error) {

});
})
.catch((error) => {

});
}
// Facebook sign-in function
function signInWithFacebook() {
var provider = new firebase.auth.FacebookAuthProvider();
firebase.auth().signInWithPopup(provider)
.then((result) => {
firebase.auth().currentUser.getIdToken(true).then(function(idToken) {
  var token = idToken;
  b4j_raiseEvent('event_register', {tk:token});
}).catch(function(error) {

});
})
.catch((error) => { 
});
}
</script>

with this you can now obtain:
DisplayName
Email
Uid
but if you need the url of the image as in my case this can help:


I am not sure (and I think not) if sending by the eval function is the most optimal in security matters but it is the way I know to make it work without at least paste the code in html and that when you give inspect the page you see the credentials of the firebase project, I hope this can help someone in the forum and if any expert reads it that can support us to explain how to do it in a safer way, greetings to all. and thanks to @tummosoft for the support with his libraries and code submitted to the forum.
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
Dim token As String = variable.Get("tk")

You can get the token without using Websocket. Check the B4J-SendingTool

B4X:
Private ServiceAccountFilePath As String = "C:\Users\H\Downloads\b4a-test1-firebase-adminsdk-9ze0o-ecfe854c74.json" 'change
Dim Token As String = GetTokenValue(ServiceAccountFilePath)

Private Sub GetTokenValue (FilePath As String) As String
    Dim GoogleCredentials As JavaObject
    GoogleCredentials.InitializeStatic("com.google.auth.oauth2.GoogleCredentials")
    Dim Credentials As JavaObject = GoogleCredentials.RunMethodJO("fromStream", Array(File.OpenInput(FilePath, ""))) _
        .RunMethod("createScoped", Array(Array As String("https://www.googleapis.com/auth/firebase.messaging")))
    Credentials.RunMethod("refreshIfExpired", Null)
    Return Credentials.RunMethodJO("getAccessToken", Null).RunMethod("getTokenValue", Null)
End Sub


Edit: Above code only works for Firebase token in B4J. I can't get token from B4A with FirebaseAuth app.
 
Last edited:
Upvote 0

aeric

Expert
Licensed User
Longtime User
Finally I managed to solve my issue with FirebaseAuth.

You need to get the token id from the client with FirebaseAuth.GetUserTokenId


B4X:
Sub Auth_SignedIn (User As FirebaseUser)
    Log("SignedIn: " & User.DisplayName)
    'CallSub(Main, "SetState")
    B4XPages.MainPage.SetState
    Log(User.Uid)
    Log(User.Email)
    auth.GetUserTokenId(User, False)
End Sub

Sub Auth_TokenAvailable (User As FirebaseUser, Success As Boolean, TokenId As String)
	Log(User)
	Log(Success)
	Log(TokenId)
End Sub
 
Upvote 0
Top