Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Login with Phone authenticated using Firebase #35

Closed
asongkai opened this issue Oct 16, 2020 · 13 comments
Closed

Login with Phone authenticated using Firebase #35

asongkai opened this issue Oct 16, 2020 · 13 comments
Labels
bug Something isn't working

Comments

@asongkai
Copy link

asongkai commented Oct 16, 2020

Hi,

I able to login with Firebase as per documentation but not able to login to chat.

String accessToken = await firebaseUser.getIdToken(true);
        signInUsingFirebase(PROJECT_ID, accessToken)
            .then((cubeUser) {
          print(cubeUser.toJson());
        })
            .catchError((error){});

image

Code:

CubeUser cubeUser = CubeUser(
    id: G.loggedInUser.id,
    login: G.loggedInUser.phone,
    password: DEFAULT_PASS,
    email: G.loggedInUser.email,
    fullName: G.loggedInUser.name,
    phone: G.loggedInUser.phone);

print(cubeUser.toJson());

if (CubeSessionManager.instance.isActiveSessionValid()) {
  _loginToCubeChat(context, cubeUser);
} else {
  createSession(cubeUser).then((cubeSession) {
    print("session:  ${cubeSession.toJson()}");
    _loginToCubeChat(context, cubeUser);
  }).catchError(_processLoginError);
}
void _loginToCubeChat(BuildContext context, CubeUser user) {
  CubeChatConnection.instance.login(user).then((cubeUser) {
    setState(() {});
  }).catchError(_processLoginError);
}

void _processLoginError(exception) {
  log("Login error $exception", TAG);
  showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Login Error"),
          content: Text("Something went wrong during login to ConnectyCube"),
          actions: <Widget>[
            FlatButton(
              child: Text("OK"),
              onPressed: () => Navigator.of(context).pop(),
            )
          ],
        );
      });
}

Error Log:

I/flutter (27584): ChatList Visibility code is 0.0
I/flutter (27584): {full_name: Hmong THAO, email: null, login: 8562096729763, phone: 8562096729763, website: null, last_request_at: null, external_user_id: null, facebook_id: null, twitter_id: null, password: xxasBUM3gQs36bhj, oldPassword: null, custom_data: null, avatar: null, tag_list: null, id: 100, created_at: null, updated_at: null}
I/flutter (27584): State: XmppConnectionState.SocketOpening
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection SocketOpening
I/chatty  (27584): uid=10323(com.oudomsup.ocwa) 1.ui identical 5 lines
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection SocketOpening
I/flutter (27584): State: XmppConnectionState.SocketOpened
I/flutter (27584): sending: <?xml version='1.0'?>
I/flutter (27584): <stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams'
I/flutter (27584): to='chat.connectycube.com'
I/flutter (27584): xml:lang='en'
I/flutter (27584): >
I/flutter (27584): unread MSG count is 0
I/flutter (27584): ChatList Visibility code is 1.0
E/flutter (27584): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: [cloud_firestore/not-found] Some requested document was not found.
E/flutter (27584): #0      MethodChannelDocumentReference.update (package:cloud_firestore_platform_interface/src/method_channel/method_channel_document_reference.dart:59:7)
E/flutter (27584): <asynchronous suspension>
E/flutter (27584): #1      DocumentReference.update (package:cloud_firestore/src/document_reference.dart:98:22)
E/flutter (27584): #2      FirebaseController.setUserState (package:OCWA/Controllers/firebaseController.dart:240:62)
E/flutter (27584): #3      _ChatState.initState.<anonymous closure> (package:OCWA/pages/chat/chat.dart:136:35)
E/flutter (27584): <asynchronous suspension>
E/flutter (27584): #4      _ChatState.initState.<anonymous closure> (package:OCWA/pages/chat/chat.dart)
E/flutter (27584): #5      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1117:15)
E/flutter (27584): #6      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1063:9)
E/flutter (27584): #7      SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:971:5)
E/flutter (27584): #8      _rootRun (dart:async/zone.dart:1190:13)
E/flutter (27584): #9      _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter (27584): #10     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter (27584): #11     _invoke (dart:ui/hooks.dart:251:10)
E/flutter (27584): #12     _drawFrame (dart:ui/hooks.dart:209:3)
E/flutter (27584):
I/flutter (27584): response: <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'>
I/flutter (27584): !!!!handle response <xmpp_stone><?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'></stream:stream></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'></stream:stream></xmpp_stone>
I/flutter (27584): processInitialStream
I/flutter (27584): unread MSG count is 0
I/flutter (27584): response: <stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features>
I/flutter (27584): !!!!handle response <xmpp_stone><stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features></xmpp_stone>
I/flutter (27584): Negotating features
I/flutter (27584): ELEMENT true
I/flutter (27584): negotiating starttls
I/flutter (27584): sending: <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
I/flutter (27584): ACTIVE FEATURE: <starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
I/flutter (27584): response: <proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>
I/flutter (27584): !!!!handle response <xmpp_stone><proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><proceed xmlns="urn:ietf:params:xml:ns:xmpp-tls"/></xmpp_stone>
I/flutter (27584): startSecureSocket
I/flutter (27584): XmppConnectionState.SocketOpened
I/flutter (27584): sending: <?xml version='1.0'?>
I/flutter (27584): <stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams'
I/flutter (27584): to='chat.connectycube.com'
I/flutter (27584): xml:lang='en'
I/flutter (27584): >
I/flutter (27584): response: <?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'>
I/flutter (27584): !!!!handle response <xmpp_stone><?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'></stream:stream></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><?xml version='1.0'?><stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='chat.connectycube.com' id='33bdd27d-e081-460d-8d37-fa8ff4162814' version='1.0' xml:lang='en'></stream:stream></xmpp_stone>
I/flutter (27584): processInitialStream
I/flutter (27584): response: <stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features>
I/flutter (27584): !!!!handle response <xmpp_stone><stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><stream:features><sm xmlns="urn:xmpp:sm:3"/><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism><mechanism>ANONYMOUS</mechanism><mechanism>PLAIN_FAST</mechanism></mechanisms><ver xmlns="urn:xmpp:features:rosterver"/><compression xmlns="http://jabber.org/features/compress"><method>zlib</method></compression></stream:features></xmpp_stone>
I/flutter (27584): Negotating features
I/flutter (27584): ELEMENT true
I/flutter (27584): sending: <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="PLAIN">ADEwMC0zNDcyAHh4YXNCVU0zZ1FzMzZiaGo=</auth>
I/flutter (27584): ACTIVE FEATURE: <mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
I/flutter (27584):   <mechanism>PLAIN</mechanism>
I/flutter (27584):   <mechanism>ANONYMOUS</mechanism>
I/flutter (27584):   <mechanism>PLAIN_FAST</mechanism>
I/flutter (27584): </mechanisms>
I/flutter (27584): response: <failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure>
I/flutter (27584): !!!!handle response <xmpp_stone><failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure></xmpp_stone>
I/flutter (27584): !!!!!!! PARSED<xmpp_stone><failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized/></failure></xmpp_stone>
I/flutter (27584): State: XmppConnectionState.AuthenticationFailure
I/flutter (27584): State: XmppConnectionState.Closing
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection AuthenticationFailure
I/chatty  (27584): uid=10323(com.oudomsup.ocwa) 1.ui identical 5 lines
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection AuthenticationFailure
I/flutter (27584): ELEMENT true
I/flutter (27584): ACTIVE FEATURE: <sm xmlns="urn:xmpp:sm:3"/>
I/flutter (27584): CB-SDK: LoginScreen.BodyState: Login error ChatConnectionException: Open connection error: AuthenticationFailure
I/flutter (27584): response: </stream:stream>
I/flutter (27584): !!!!handle response
I/flutter (27584): Handle secured connection done
I/flutter (27584): State: XmppConnectionState.Closed
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection Closed
I/chatty  (27584): uid=10323(com.oudomsup.ocwa) 1.ui identical 5 lines
I/flutter (27584): CB-SDK: CubeChatConnection: Chat connection Closed
@TatankaConCube
Copy link
Contributor

@asongkai just use 'token' as a password for the user. For it before call _loginToCubeChat(context, cubeUser); do

// get current ConnectyCube session token and set as user's password
String token = CubeSessionManager.instance.activeSession?.token;
cubeUser.password = token;

More detail in our documentation.

@asongkai
Copy link
Author

Thank you for response!

I'm not sure what is really happening, I do as mentioned but still not able to login

Error Log:

I/flutter (26426): CB-SDK: : *********************************************************
I/flutter (26426): *** RESPONSE *** 201 *** 916d7423-9bfd-4bf4-a8e2-58d1804d958d ***
I/flutter (26426): HEADERS
I/flutter (26426):   {connection: keep-alive, cache-control: max-age=0, private, must-revalidate, set-cookie: _mkra_ctxt=39641ae6a6e83b9b4e66cc7f5d81667c--201; path=/; max-age=5; HttpOnly; secure, status: 201 Created, transfer-encoding: chunked, date: Sat, 17 Oct 2020 00:00:15 GMT, access-control-allow-origin: *, strict-transport-security: max-age=31536000,max-age=15768000;, content-type: application/json; charset=utf-8, x-xss-protection: 1; mode=block, server: nginx/1.16.1, x-request-id: d60d5eff-7339-448f-b808-aeea4efe4233, cb-token-expirationdate: 2020-10-17 02:00:14 UTC, connectycube-rest-api-version: 0.1.1, x-runtime: 0.021856, etag: W/"4fe0f78a28b91bcaf0814758c1a9a247", x-frame-options: SAMEORIGIN, x-content-type-options: nosniff}
I/flutter (26426): BODY
I/flutter (26426):   {"session":{"id":18343448,"user_id":0,"application_id":3472,"nonce":3161826250,"token":"f6181faa591cd70390b1ec045e84bffc9d000d90","ts":1602892815,"created_at":"2020-10-17T00:00:15Z","updated_at":"2020-10-17T00:00:15Z"}}
I/flutter (26426): 
I/flutter (26426): CB-SDK: : =========================================================
I/flutter (26426): === REQUEST ==== e1f408f2-a527-4e33-84a1-1406265f2dac ===
I/flutter (26426): REQUEST
I/flutter (26426):   POST https://api.connectycube.com/session 
I/flutter (26426): HEADERS
I/flutter (26426):   {Content-type: application/json, ConnectyCube-REST-API-Version: 0.1.1, CB-SDK: Flutter 0.5.0, CB-Token: f6181faa591cd70390b1ec045e84bffc9d000d90}
I/flutter (26426): BODY
I/flutter (26426):   {"application_id":"3472","auth_key":"2SQ7ewuGSdVvA6f","nonce":"292839984","timestamp":"1602892816","signature":"73c0466a899148858b870c070863b2f20908c66c","user":{"login":"8562096729763","password":"f6181faa591cd70390b1ec045e84bffc9d000d90"}}
I/flutter (26426): 
I/flutter (26426): CB-SDK: : *********************************************************
I/flutter (26426): *** RESPONSE *** 401 *** e1f408f2-a527-4e33-84a1-1406265f2dac ***
I/flutter (26426): HEADERS
I/flutter (26426):   {connection: keep-alive, set-cookie: _mkra_ctxt=475cb6b3cf998eb82441327fa0736d57--401; path=/; max-age=5; HttpOnly; secure, cache-control: no-cache, status: 401 Unauthorized, transfer-encoding: chunked, date: Sat, 17 Oct 2020 00:00:17 GMT, access-control-allow-origin: *, strict-transport-security: max-age=31536000, content-type: application/json; charset=utf-8, x-xss-protection: 1; mode=block, server: nginx/1.16.1, x-request-id: 97591e6f-dd31-495b-8484-c8475e308719, connectycube-rest-api-version: 0.1.1, x-runtime: 0.025420, x-frame-options: SAMEORIGIN, x-content-type-options: nosniff}
I/flutter (26426): BODY
I/flutter (26426):   {"errors":["Unauthorized"]}
I/flutter (26426): 
I/flutter (26426): CB-SDK: LoginScreen.BodyState: Login error ResponseException: 401: {"errors":["Unauthorized"]}

Updated Code:

createSession()
          .then((cubeSession) {
        CubeUser cubeUser = CubeUser(
            id: G.loggedInUser.id,
            login: G.loggedInUser.phone,
            password: CubeSessionManager.instance.activeSession?.token,
            email: G.loggedInUser.email,
            fullName: G.loggedInUser.name,
            phone: G.loggedInUser.phone);

        if (CubeSessionManager.instance.isActiveSessionValid()) {
          String token = CubeSessionManager.instance.activeSession?.token;
          cubeUser.password = token;
          _loginToCubeChat(context, cubeUser);
        } else {
          createSession(cubeUser).then((cubeSession) {
            String token = CubeSessionManager.instance.activeSession?.token;
            cubeUser.password = token;
            _loginToCubeChat(context, cubeUser);
          }).catchError(_processLoginError);
        }
      })
          .catchError((error) {});

@TatankaConCube
Copy link
Contributor

You misunderstood me, you have to use the token as a password only for chat connection, not everywhere. It means you have to authorize via Firebase phone auth first, then use this token for chat login.

@asongkai
Copy link
Author

asongkai commented Oct 17, 2020

Hi,

I used the following code it works but I have another question,

loginToChat() async {
    createSession()
        .then((cubeSession) async {
      CubeUser cubeUser = CubeUser(
          id: G.loggedInUser.id,
          login: G.loggedInUser.phone,
          password: CubeSessionManager.instance.activeSession?.token,
          email: G.loggedInUser.email,
          fullName: G.loggedInUser.name,
          phone: G.loggedInUser.phone);

      if (CubeSessionManager.instance.isActiveSessionValid()) {
        String token = CubeSessionManager.instance.activeSession?.token;
        cubeUser.password = token;
        print('Token valid');
        print(cubeUser.toJson());
        _loginToCubeChat(context, cubeUser);
      } else {
        print('Token invalid');
        String accessToken = await FirebaseAuth.instance.currentUser.getIdToken(true);
        signInUsingFirebase(PROJECT_ID, accessToken)
            .then((cubeUser) async {
          String token = CubeSessionManager.instance.activeSession?.token;
          cubeUser.password = token;
          print('password: $token');
          createSession(cubeUser).then((cubeSession) {
            _loginToCubeChat(context, cubeUser);
          }).catchError(_processLoginError);
        })
            .catchError((error){
          print(error);
        });
      }
    })
        .catchError((error) {});
  }

Do I need to create a new Session token and login to chat every time the app open? or Connectycube manage the session like Firebase instance?

because I tried to put them in separate method only response like "unauthenticate", "session invalid".

@TatankaConCube
Copy link
Contributor

No, in the current realisation of our Flutter SDK we don't have an automatic session management, you have to realise it by yourself.

@asongkai
Copy link
Author

As I mentioned above once I can login and created the user session if I close the app and reopen the session has gone which can't use other feature like chat or video call that's force me to login every time I open my app and the process of logging in is so slow too which make my app load slow at the start.

@asongkai
Copy link
Author

The demo app also same if I close the app and reopen the session has gone the same, need to select a user again and login again

So, once I authenticated with firebase and I try to create the user session token in a separate thread it only show me "Unauthorized" message on response so the solution for my case now is like I posted the code above

I mentioned firebase instance because "Yes, I have to do the user session by myself in order to redirect user to login or home screen" but I don't have to authenticate again or login again to be able to use the chat or video feature.

but current case is once I logged in I can use but if I close the app and reopen and go to use chat or video it said "Unauthenticated"

@TatankaConCube
Copy link
Contributor

As I said before, the current version of our SDK doesn't have a session manager yet and you can realize it by yourself.
There can be oriented steps:

  • save needed session data (session, token expiration date, login, password, auth token, etc) to secure storage;
  • before performing any request, check if the session expired, need to create a new with saved data, then perform request;
  • if the saved session not expired, just set the saved session to SDK via CubeSessionManager.instance.activeSession = session;, then perform needed requests.

@asongkai
Copy link
Author

Thank you very much I will give that try

@asongkai
Copy link
Author

asongkai commented Oct 21, 2020

Hi,

I do as you mentioned by why the token expiry date is always null

      String accessToken =
            await FirebaseAuth.instance.currentUser.getIdToken(true);
        signInUsingFirebase(PROJECT_ID, accessToken).then((cubeUser) async {
          String token = CubeSessionManager.instance.activeSession?.token;
          cubeUser.password = token;
          createSession(cubeUser).then((cubeSession) {
            services.setValue('token', cubeSession.token);
            services.setValue('token_expire', cubeSession.tokenExpirationDate);
            print('token_token: ${cubeSession.token}');
            print('token_expire: ${cubeSession.tokenExpirationDate}');
            _loginToCubeChat(context, cubeUser);
          }).catchError(_processLoginError);
        }).catchError((error) {
          print(error);
        });

What's wrong?

image

@TatankaConCube TatankaConCube added the bug Something isn't working label Oct 21, 2020
@TatankaConCube
Copy link
Contributor

TatankaConCube commented Oct 21, 2020

why the token expiry date is always null

we found the issue on the SDK side, we will provide fixes in the next release, thank you for your checks.

@TatankaConCube
Copy link
Contributor

@asongkai today we released version 0.5.1 with required fixes for your issue.
But pay attention, you should use this way for getting the expiration date CubeSessionManager.instance.getTokenExpirationDate(); because any successful API request prolongs the token validity for 2 hours. More in our documentation for server API.

@TatankaConCube
Copy link
Contributor

Closing. If you have a similar issue in the latest version, please create a new ticket with a description according to templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants