PubSub messaging breaks on user logout

Backendless Version (6.1.2)

Client SDK (Objective-C)

Application ID B69AC5CA-35FA-097A-FF2C-8AE7BFD8C900

Test example app

To demonstrate the bug we prepared the minimal Objective-C macOS app for probing the issue. The app’s project is attached in the zip file. All our testing is done in RELEASE build configuration.

BackendlessTest.zip (13.8 MB)

Expected Behavior

  1. Start the app in release mode.
  2. Press ‘Login’ button to login with the test user (wait for successful login message)
  3. Press ‘Join default channel’
  4. Press ‘Add string message listener’
  5. Open your terminal and enter the curl command for publishing the message in the app’s default channel:
    curl -X POST
    https://api.backendless.com/B69AC5CA-35FA-097A-FF2C-8AE7BFD8C900/0278795F-7C5A-4F48-94F4-61B9D6954FF3/messaging/default
    -H ‘content-type: application/json’
    -d ‘{ “message”: “message” }’
  6. You should see in the app’s output log the received message.
  7. Press ‘Logout’
  8. Repeat the message publishing command from step 5.
  9. You should again see the received message in the app’s output log.
  10. Press ‘Is default channel joined’ and it should log that the channel is indeed joined.
  11. Press ‘Leave default channel’
  12. Press ‘Join default channel’ (wait for channel to join).
  13. Press ‘Is default channel joined’ and it should log that the channel is indeed joined.

Actual Behavior

  1. Start the app in release mode.
  2. Press ‘Login’ button to login with the test user (wait for successful login message)
  3. Press ‘Join default channel’
  4. Press ‘Add string message listener’
  5. Open your terminal and enter the curl command for publishing the message in the app’s default channel:
    curl -X POST
    https://api.backendless.com/B69AC5CA-35FA-097A-FF2C-8AE7BFD8C900/0278795F-7C5A-4F48-94F4-61B9D6954FF3/messaging/default
    -H ‘content-type: application/json’
    -d ‘{ “message”: “message” }’
  6. You should see in the app’s output log the received message.
  7. Press ‘Logout’
  8. Repeat the message publishing command from step 5.
  9. The message is never received although the default channel is still joined.
  10. Press ‘Is default channel joined’ and it should log that the channel is indeed joined.
  11. Press ‘Leave default channel’
  12. Press ‘Join default channel’ (you should wait and see that the default channel is never joined again).
  13. Press ‘Is default channel joined’ and it should log that the channel is not joined.

We noticed that on user logout (step 7) the Backendless messaging stops working properly on the client side. It seems that TCP connections responsible for the RT Messaging are closed for some reason and can’t be opened again by joining the channel. Our expectations are that we should still be able to use messaging after user logout. Even if we try to login again after logout, messaging still doesn’t work - we can’t receive the messages published to the channel we subscribed to. But message publishing still works.

We noticed the similar issue when we loose internet connectivity. To test this we turned off and on the wifi and we couldn’t receive the pubsub messages anymore.

Here is our app’s output log for the steps provided above:

Started login…
User has been logged in.
Started default channel join…
Default channel joined.
String message listener added.
Received message from default channel: message
Started logout…
User has been logged out
Default channel is joined: 1
Default channel should be left. Check with button ‘Is default channel joined.’
Started default channel join…
Default channel is joined: 0

Hello @Hrvoje_Ditrih

Welcome to our community and thank you for trying out Backendless.

We are looking into it.

I have created internal ticket for this problem BKNDLSS-23512.
We will notify you for results.

Hello @Hrvoje_Ditrih,
Issue is fixed in Swift-SDK v6.1.3.1.
After user is logged out there is no need to reconnect the channel - it will be done automatically.
According to the internet connectivity loss - I can advise you to add these connection listeners:

[Backendless.shared.rt addConnectErrorEventListenerWithResponseHandler:^(NSString *reason) {
	NSLog(@"Socket connection failed: %@", reason);
}];
    
[Backendless.shared.rt addDisсonnectEventListenerWithResponseHandler:^(NSString *reason) {
	NSLog(@"Socket disconnected: %@", reason);
}];
    
[Backendless.shared.rt addReconnectAttemptEventListenerWithResponseHandler:^(ReconnectAttemptObject *reconnect) {
	NSLog(@"Trying toreconnect socket");
}];

You will be notified when Socket connection is dropped and this connection will be recreated automatically with the reconnectAttemptEventListener.
Hope this would be helpful.

Regards,
Olha

Hello @olhadanylova,
Thee issue with logout seems to be fixed.
However, the issue regarding the internet connectivity, seems to be fixed only when I add the listeners you mentioned. Shouldn’t the sockets reconnect regardless of the aforementioned listeners?

Hello @Hrvoje_Ditrih ,

The autoreconnection is turned off in our SDK because socket connection requires some additional settings and checks before reconnect.
We don’t track the Internet connection status in our SDK, and listeners help to recognize whether socket is connected or not and the reason for this (because socket disconnection can occur not only when Internet connection is not stable but for other reasons to).
However, I’ve created an internal ticket BKNDLSS-23739 to investigate this case and I’ll let you know here when it is done.

Regards,
Olha

Moreover, after updating to the v6.1.3.1. our whole pubsub system breaks. The issue seems to be that whenever we update a field on backendless user, the pubsub channels automatically join again.

Here is our code for setting isOnline flag for our user and we call this method periodically:

-(void)updateOnlineStatusOnServer {
    BackendlessUser* currUser = _appModel.currUser;
    if (currUser) {
        [currUser setPropertyWithPropertyName:@"isOnline" propertyValue:@(YES)];
        [Backendless.shared.userService updateWithUser:currUser responseHandler:^(BackendlessUser *updatedUser) {
            NSLog(@"User online status updated!");
        } errorHandler:^(Fault *fault) {
            NSLog(@"Error updating online status: %@", fault.message);
        }];
    }
}

Whenever this code is called, our pubsub channels join again automatically which causes that rt messaging stops working properly - our testing shows that we don’t receive all the messages we should receive.

Please provide steps to reproduce the issue with user update because the next scenario works fine for me:

  1. login
  2. join default channel
  3. add message listener
  4. send message - message is received
  5. update user - user is successfully updated
  6. send message - message is received
  7. logout
  8. wait until channel is joined automatically again (it’s an expected behaviour because we need to reconnect socket after logout with a new settings and then resubscribe for all subscriptions including messaging)
  9. send message - message is received
  10. login
  11. wait until channel is rejoined automatically again (it’s an expected behaviour because we need to reconnect socket after login with a new settings)
  12. send message - message is received
  13. update user - user is successfully updated
  14. send message - message is received

Regards,
Olha

Hello @Hrvoje_Ditrih,

A new version of Swift-SDK v6.2.1.1 with fixes is released. Could you please check?

Regards,
Olha

Hello,

The issue with reconnect after the internet disconnects is now solved.

But there is still an issue when updating user with:
[Backendless.shared.userService updateWithUser:]

We discovered that when the stay logged in flag is set:
Backendless.shared.userService.stayLoggedIn = YES;
and when user update is called the joined channels join again.

I’ll check this. Ticket number is BKNDLSS-23739.

Regards,
Olha

It seems like that stayLoggedIn flag forces the socket to reconnect, on user update, whilst re-joining all joined channels.

For us, the stayLoggedIn flag in conjunction with validating user token doesn’t work as expected - even if we set the flag to NO, when the app relaunches the user token will still be valid.

Hi @olhadanylova ,

Can you please expedite this issue with your development team? We need to release our app and this is one of the main issues we encounter.
As Hrvoje mentioned, the issue arises when the Backendless.shared.userService.stayLoggedIn = YES; flag is set.
Even though the disconnect issues have been fixed with some of the later builds, the problem where the flag is set causes the malfunction in PubSub subscription where it breaks completely, user cannot receive any messages anymore which is a dealbreaker for us.

I see another couple of builds after your last interaction with our dev, however they don’t seem to be related to our use case - can you confirm?

Thanks for your help so far.

Best,

Matej.

Hello @Matej_Trbara,

The ticket is in progress right now and the fix will arrive soon.
However, I’d ask you to provide steps of the expected and current behaviour to test the fix as close as possible to your scenario (as it was done in the first comment).

Regards,
Olha

Hello,
issue with channel reconnection after current user update is fixed.
Please check with Swift-SDK v6.2.5.

Here are steps of our tests:

  1. login user
  2. connect to the default channel
  3. add message listener
  4. send message - the message is received
  5. update user
  6. send message - the message is received
  7. logout user - the default channel is rejoined automatically as expected
  8. send message - the message is received
  9. check token - token is invalid (because user was logged out)
  10. login user - the default channel is rejoined automatically as expected
  11. check token - token is valid
  12. send message - the message is received

Please provide your steps if issue still occurs.

Regards,
Olha

Hi @olhadanylova ,

There is still a certain situation when RT messaging stops working (Swift-SDK v6.2.10.). Here are steps to reproduce the issue.

  1. login user
  2. connect to channel
  3. add message listener
  4. send message - the message is received
  5. logout user

These next steps you need to do fast one after the other. You can wait for user to properly login but then you need to remove and add message listeners very fast.

  1. login user
  2. remove message listeners (do it fast after 6.)
  3. add message listener (do it fast after 7.)
  4. remove message listener (do it fast after 8.)
  5. add message listener do it fast after 9.)
  6. send message - the message is not received

Regards,
Hrvoje

Hello @olhadanylova

Our engineer will check and write here additionally about the result.

Hello @Hrvoje_Ditrih,

Please check with v6.3.0.

Regards,
Olha

Hi @olhadanylova ,

The problem still isn’t fixed. After you do logout and then login there is a period when Backendless reconnects. You can track the Backendless connection with these listeners:
Backendless.shared.rt addConnectEventListenerWithResponseHandler
and
Backendless.shared.rt addDisсonnectEventListenerWithResponseHandler

After logout and then login, there are few seconds after Beckendless connects. If you add/remove message listners in a period when Backendless still isn’t connected they won’t work. If you add/remove message listeners after Backendless connect, it works fine.

Regards,
Hrvoje

Hi @olhadanylova,

Also on the note of the general Swift-Backendless SDK. There are numerous issues when using login/logout. It’s very hard to reproduce these issues, for eg. the last issue I reported took me 2 months to figure out how to reproduce the issue on a minimal example. It would be very benefitial for us if you could do a close examination of login/logout and everything that is connected to it and fix those issues.

We have been using Backendless for more than 4 months now and our app still can’t logout/login properly. Sometime it works fine and sometimes the whole app breaks after user does login after logout because of some issue with Backendless. Our temporary fix for this situation is that when the user wants to logout we quit the app after logout. Then login works properly after fresh startup of the app. It would be great for us if you could examine the login/logout workflow and make sure that Backendless works the same after them.

Best,
Hrvoje