RodrigoBertotti / flutter_chat_app_with_nodejs

A Flutter Chat App built with Node.js, MySQL, and WebSockets.
MIT License
73 stars 29 forks source link

Askless throwing errors #1

Open DannyFilo opened 10 months ago

DannyFilo commented 10 months ago

Hello, when running your original code Askless is runnig errors all the time (when running npm server + 2 flutter clients connected).

Additionally after loggin-in loggin-out on the flutter client ... messages "from today" dissapear and are not showing on both clients (although chat works)

No idea how to fix it. Would you also be so kind and add small doc how to change column names in database ? Seems your code is havy "column name" dependend (all 3 packages npm server, askless library and flutter code). For example changing "userId" in database to "Id" .. seems to be really heavy work.

Flutter app side errors

I/flutter (12514): listenToTypingSubscription CALLED I/flutter (12514): Askless [ERROR]: (waitForAuthentication) Ops, this shouldn't happen, the App says it is authenticated but the server says is not authenticated I/chatty (12514): uid=10173(com.wisetap.flutter_chat_app_with_mysql.flutter_chat_app_with_mysql) 1.ui identical 1 line I/flutter (12514): Askless [ERROR]: (waitForAuthentication) Ops, this shouldn't happen, the App says it is authenticated but the server says is not authenticated

NPM server errors

onReceived MESSAGES: notifyMessagesWereUpdated: {"receivedAt":"2023-10-12T11:41:26.274Z","senderHasOutdatedVersion":true} info: onClientReceiveOutputWithSuccess being ignored for route messages-were-updated (listen) onReceived messages callback: messages senderReceivedMessagesUpdates is empty/null warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)askless-internal/call/receive, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"askless-internal/call/receive\" because authentication is required"} error: onClientStartsListening not called [READ/LISTEN] conversations-with-unreceived-messages has been called by the client 1": conversations-with-unreceived-messages" sending -> [] info: onClientReceiveOutputWithSuccess being ignored for route conversations-with-unreceived-messages (listen) info: onClientReceiveOutputWithSuccess being ignored for route askless-internal/call/receive (listen)

RodrigoBertotti commented 10 months ago

Hello! Thank you for opening the issue

I will follow your suggestion of keeping the messages after logging in again after a logout, I will do it and I let you know here

To rename the field userId in the db to id you have two ways of doing it:

I will also check the message Ops, this shouldn't happen, the App says it is authenticated but the server says is not authenticated and fix it, I will let you here in this issue as well

thanks for reaching out, any questions let me know

DannyFilo commented 10 months ago

Many thanks for such a quick reply ! It's a really interesting project also from learning perspective. Really appreaciate your help on the "Ops" issue.

I tried to refactor userId in user-entity.ts, but seems there's also userId used on flutter side. I will review this file by file and try to do it manually. I Wanted to experiment with existing mysql chat database we use for php website at school where colum names are totally different (simple mobile chat would be a great add-on), so I guess there might be some manual work.

Would you be so kind and tell what's the easiest way to: 1) add simple "WHERE" filter (ideally on flutter side) to select specific filtered user dataset as "Contacts" ? (now it's all<->all users) 2) force messages refresh on flutter app side chat conversations (so database status) when one user is writing via php website and another is reading via flutter app ? 3) delete conversation from the flutter app

Many thanks in advance, enjoy your day !

RodrigoBertotti commented 10 months ago

Sorry, in case you choose the first option, I forgot to tell you to refactor userId in the Flutter side as well

about the first item, looks like you want to show only common friends of the user (not all users), so in this case you may want to change the implementation of the files nodejs_websocket_backend/src/controllers/user-controller/user-controller.ts (user-list) and change the implementation of getAllUsers()

about the second item, it would be very tricky to implement, because Askless is not designed to work with other backends simultaneously, I would try to have Askless server in the backend and also a Express server to receive webhooks from PHP, Askless + Express in the same node.js backend, so for example, PHP would tell express that a user typed, and express would call messagesService.notifyUserIsTyping(loggedUserId, receiverUserId), but I'm not sure if this would work because I never tried using rest + websocket (askless) simultaneously, but it's something I would try

to delete the conversation from a flutter app, you can use as reference the createMessage in the node.js (nodejs_websocket_backend/src/domain/services/messages-service.ts) and sendMessage (flutter_app/lib/features/chat/data/data_sources/messages_remote_ds.dart) in the flutter side to follow a similar logic. You need to also delete the local messages in the flutter side in the flutter_app/lib/features/chat/data/data_sources/messages_local_ds.dart file as well

DannyFilo commented 10 months ago

Many thanks for your all priceless suggestions. I will follow them and try to implement a solution with shared mysql DB (php / flutter node.js).

Just last one ... I already have access_token I use in my Flutter prototype App. It's taken via separate login by REST API talking to our mysql. Would you suggest any easy method to skip user/password authentication in your flutter client just use access_token only I can provide as variable from my flutter prototype to your Flutter-chat module ?

1000 Thanks again !

RodrigoBertotti commented 10 months ago

I appreciate!

On the Flutter side, you can go to the flutter_app/lib/features/login_and_registration/data/data_sources/auth_remote_ds.dart file and change the code of the getAccessTokenWithEmailAndPassword(..) function, remove AsklessClient.instance.create(route: "login" ...) and replace it with a call to your REST API so you can verify the access token directly with your REST API. You may also want to edit useRefreshTokenToGetNewAccessToken(..) in case the access token is no longer valid

In the backend, you can change the code of the authenticate(...) function from the nodejs_websocket_backend/src/index.ts file so you can replace it with your logic to validate your accessToken

I hope it helps

DannyFilo commented 10 months ago

a million thanks Rodrigo ! I will have an excellent weekend experimenting with your project !

RodrigoBertotti commented 10 months ago

I let you know once I release an update! I wish you success in your project and an awesome weekend!

DannyFilo commented 10 months ago

Hello Rodrigo,

Hope all is well. So I finally managed to refactor all my columns and also have changed authorization system. After analysing your code on both flutter and node.js sides I decided to leave original token management between flutter client -> askless and node.js. It's a different form of authorisation used only for chat purpose, so I figured out that the best way will be to replace your email/password by my user_access_token. Refactored few methods and it works ! :)

I hope you don't mind to ask some simple questions - Since now I use chat as sub-module in my main app at school (users are authorized by their username and password in other module) and chat is only authorised via API user_access_token I got from the server:

1) How to disable refresh_token_access on the chat app ? or do I have to do it at all since it's only chat authorisation, maybe better to keep it ? appreciate your opinion.

2) How to keep chat_app permanently logged in ? I know that in your original chat_app version you're currently checking whether password and email are saved in some internal repository (Hive) and then keeping user logged in. I wonder how to adopt this to my user_access_token authorisation. To keep user permanently logged in wheh his token is valid and saved.

3) Is there any part of the code which is logging out user after certain timeout from chat_app ? I'd like to disable this part.

4) then when I log out user from the main_app ... should I also log out user on the chat level ?

5) and last one ... did you maybe figure out how to display recent messages to user when he's logging into app (in a given certain time like T=last 3 days)

ops ... apologies .... probably too much questions :)

many thanks in advance ! Danny

RodrigoBertotti commented 10 months ago

Hi! I'm glad you are progressing well! Congratulations

Actually, the user email and password are not saved in the user device, but the access token and refresh token are, I think the best option for you is to keep this logic as it is, and in the backend you can change the async login(email: string, password: string) function in the flutter_chat_app_with_nodejs/nodejs_websocket_backend/src/domain/services/auth-service.ts file

So instead of validating the user email and password in the chat db, you can validate in your school db instead, but the refresh token and access token logic you can keep it as it is, in this way, the user is supposed to be permanently logged in. Also, there's no part in the app that logs out the user after a timeout, but this will happen in case the onAutoReauthenticationFails(..) function is called in the flutter_app/lib/core/data/repositories/auth_repo_impl.dart file

So in this way, by keeping the access token and refresh token logic, you don't need to log out the user in the chat app when he logs out in the main app (but you can do it if you want to), because the Chat tokens logic is different from the School tokens logic, the only thing that will be similar is the validation of the password

About the last item, you can create a new route similar to messages route, check these files, it will give you a better direction:

DannyFilo commented 10 months ago

1000 thanks ! I will be developing this during weekend. Hope I can manage :)

DannyFilo commented 9 months ago

Hello Rodrigo, hope all is well at your end. I was wondering if you've had time to look into Askless [ERROR]: (waitForAuthentication) Ops, this shouldn't happen, the App says it is authenticated but the server says is not authenticated ... Still working on my school chat, but got this error so often and to be honest I've stuck with it. No idea what's the reason and how to fix it.

RodrigoBertotti commented 9 months ago

Got it, thanks for letting me know, I will add this to my list and I let you know here

RodrigoBertotti commented 9 months ago

Hello DannyFilo, I just noticed that the error message was appearing at the wrong time, the branch dev has the adjustment, thanks again

I will let you know here when I implement the feature of keeping the messages when the user logs in after a logout

DannyFilo commented 9 months ago

Oh many thanks ! I planned to continue working on my mini project this weekend, so for sure I will incorporate your update.

I was wondering on 2 things:

Many thanks for the update again, Danny

RodrigoBertotti commented 9 months ago

Sure, there's two ways of doing, with streamConnectionChanges(...) and with addOnConnectionChangeListener(...),

It only works for showing the connection status of the local user for himself, is this what you want? Or do you want to let a remote user know whether the local user is connected or not?

I'm glad you are making progress and letting me know! Thank you for that, I'm not aware of this second issue, but I will make tests. Could you please go to the flutter_app/lib/core/data/data_sources/connection_remote_ds.dart file and set debugLogs to true temporally, and send me logs in case happen again? I appreciate it

DannyFilo commented 9 months ago

Oh I meant to show other users if someone's is online / offline. Adding some sort of green/grey light icon on all contacts.

Many thanks for a hint with debug option - I will make some more extensive testing this weekend, so for sure I will send the logs. There's might sort of instabilty on software side. Not sure what is it. Sometimes server is running, all is good and then I send message from one chat client to another (android simulator 1 to simulator 2) and I see infinite logs running like below. Like one of listeners died or askless authentication token / expired or got lost somehow. Only server restart helps. I will try to analyse this with debug option on.

Have a nice weekend and many thanks.


warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client " (no ID) " could not perform the operation on (CREATE)message, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)conversations-with-any-messages, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"conversations-with-any-messages\" because authentication is required"} error: onClientStartsListening not called warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)askless-internal/call/receive, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"askless-internal/call/receive\" because authentication is required"} error: onClientStartsListening not called warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)user-list, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"user-list\" because authentication is required"} error: onClientStartsListening not called warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)is-typing, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"is-typing\" because authentication is required"} error: onClientStartsListening not called warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)messages, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening... {"code":"PENDING_AUTHENTICATION","description":"Could not perform the operation on (LISTEN) \"messages\" because authentication is required"} error: onClientStartsListening not called warning: respondWithError: the client "(no ID)" could not perform the operation on (READ)messages-were-updated, result is PENDING_AUTHENTICATION, authentication is "pending", did you handle the onUnauthenticatedListener on the App side? (initAndConnect) error: listen: the error is "PENDING_AUTHENTICATION", calling stopListening...

RodrigoBertotti commented 9 months ago

Right now Askless doesn't support this feature, but thanks for asking me, I will keep this in mind in case more people request it

Thanks also for sharing your logs, could you please also share your Flutter and Node.js versions?

DannyFilo commented 5 months ago

Hello Rodrigo, hope all is well. It's been a long time. I had a quite a few disturbing months with some sickness. Now fortunately I'm back life and back to some development work and fun with chat app. I will probably have 1 or 2 questions in the coming days. First I had to remind myself how askless work :) ...

I have a first small request ... I had to update my small project to compileSdkVersion 34 ... and unfortunately this new SDK is working with latest version of Gradle which requires namespace in every package. Your Askless library has still a dependency on old package safe_device. I see there's a new version of this one.

Would you find a minute and update Askless with latest versions of safe_device package + others ? That would help a bit in my small neverending project :)

Kind regards, Daniel

RodrigoBertotti commented 5 months ago

Hello DannyFilo, how bad! But I'm happy you are good now

Sure, you can now update the askless package to ^3.1.0 in pubspec.yaml

Take care

hieunt1320 commented 3 months ago

Hello rodrigro, i made a new issue but saw no respond so i hope you can help me with the issue i faced, namely the disconnected issue and a few more but i would love to have your respond first

thanks in advance

Hieunt

RodrigoBertotti commented 2 weeks ago

A new update has been released with a focus on fixing issues, so run git pull :)