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

Update user profile #456

Closed
borutlatecheckout opened this issue Mar 8, 2024 · 18 comments
Closed

Update user profile #456

borutlatecheckout opened this issue Mar 8, 2024 · 18 comments
Labels
bug Something isn't working

Comments

@borutlatecheckout
Copy link

What are you trying to achieve?

I want to update user profile and see changes in the channel afterwards.

If possible, how can you achieve this currently?

We are updating profile on the BE atm and once this is done, we restart the chat. But there is a slight delay after which we get updated info to be reflected in the channel.

What would be the better way?

I would like to know what is the best solution for this scenario?
Is there maybe a function in SDK to update current user profile?

GetStream Environment

GetStream Chat version: latest
GetStream Chat frameworks: StreamChat, StreamChatUI
iOS version: 17
Swift version: 5.10
Xcode version: 15.x
Device: iPhone

Additional context

@nuno-vieira
Copy link
Member

Hi @borutlatecheckout,

Can you share a video of your use case? What do you mean by delay? What information are you updating from the user? Is it only the name or the image?

Best,
Nuno

@borutlatecheckout
Copy link
Author

Hi @borutlatecheckout,

Can you share a video of your use case? What do you mean by delay? What information are you updating from the user? Is it only the name or the image?

Best, Nuno

Hi @nuno-vieira. Maybe I wasn't clear enough. Let me try to explain it better.

We have mobile app and a backend. When user changes his name or profile picture in the mobile app, we update this info on the backend and backend also uses the StreamChat API to update chat user name and picture.

On success, mobile calls client.disconnect to reset the chat session and then starts it again (restart).

What we are observing is the following:

  1. If we "restart" the chat immediately after we get success from the backend (which means profile info was also updated on the StreamChat), the chat would returned the old profile data (old picture, or name or both).
  2. If we "restart" the chat with 2 second delay (so we wait a bit), usually chat returns the updated profile info. We've assumed that some caches needs to purged on StreamChat end before we can get the new values.

That 2 second delay is our prediction that it should work and at the same time it doesn't hurt UX since by the time user gets back to the chat from the profile editing, it takes ~2 seconds if he is quick.

But we managed to replicate the same issue even with 2 second delay. And this is the culprit we want to solve. We would like to know when is the good time to "restart" the chat to get up-to-date data.

I hope this is a bit more clear on where is the issue and what we are facing atm.

I thought user changes are reflected automatically using StreamChat SDK, but they are not.

Any help or suggestion would be very welcome.

Thanks

@nuno-vieira
Copy link
Member

Hi @borutlatecheckout,

I'm not sure I'm still understanding 100%.

On success, mobile calls client.disconnect to reset the chat session and then starts it again (restart).

Why are you calling disconnect whenever the user updates the info? Also, when you connect the user, are you updating the user information there? Maybe it is overriding whatever is set from the backend?

Either way, if you change the profile data, you should not reset the connection, the user data will be updated without any action on your side.

Best,
Nuno

@borutlatecheckout
Copy link
Author

Hey @nuno-vieira.

When I connect the user to chat, I provide the latest id, name and pictureUrl. But that is only at the initialization. When we change the user info, there is no method in the SDK to update info (at least I'm not aware of it).

So let me write you a scenario:

  1. user opens the app, chat is initialized with his id, name and pictureUrl
  2. user goes to settings and changes his name; our backend is invoked which also updates the user info on the StreamChat API
  3. user goes back to the chat

Now we have two choices:

  1. user kills the app and the chat will get the updated name
  2. we wait a few seconds, re-initialize the chat and updated name is there

If we do not take any actions and just return to the chat, name is not updated until I send a new message or new message is received. I think that the iOS SDK doesn't receive the update event, therefore nothing is updated on the UI side. But only when some action is performed.

Am I missing smth?

@nuno-vieira
Copy link
Member

Hi @borutlatecheckout,

When we change the user info, there is no method in the SDK to update info (at least, I'm not aware of it).

There is an update method, indeed. You need to use CurrentChatUserController.updateUserData(). Something like this:

let currentUserController = ChatClient.shared.currentUserController()
currentUserController.updateUserData(...)

This way, everything is handled automatically, and user-updated events are correctly triggered in the SDK. By the way, are you using the UI SDK, or only Low-level SDK?

Best,
Nuno

@nuno-vieira
Copy link
Member

I'm closing this one for now.

But do let us know if you are still having problems.

Best,
Nuno

@borutlatecheckout
Copy link
Author

@nuno-vieira thanks for the update. I've tried the following:

  /// Update user info
  func updateUser(name: String, pictureURL: URL?) {
    let controller = client.currentUserController()
    controller.updateUserData(name: name, imageURL: pictureURL) { error in
      if let error {
        print(error)
      }
    }
  }

But unfortunately this doesn't work either. No error is returned. The profile isn't updated until I restart chat session.
I'm using UI SDK.

@nuno-vieira
Copy link
Member

@borutlatecheckout Which view the profile is not updated?

@borutlatecheckout
Copy link
Author

The main chat channel view where we have all the messages listed. This is how I

struct ChatView: View {
  @ObservedObject var viewModel: ChatViewModel

  var body: some View {
    ChatChannelView(
      viewFactory: ChatViewFactory(
          chatClient: viewModel.chatService.client,
          name: viewModel.userFirstName
      ),
      channelController: controller
    )
  }
}

@nuno-vieira nuno-vieira reopened this Mar 14, 2024
@nuno-vieira
Copy link
Member

I see, this might be a SwiftUI SDK issue, then, or something wrong with your SwiftUI integration. I'm going to transfer the issue to the SwiftUI repo, and @martinmitrevski will investigate as soon as he can. But the user profile names and images are correctly updated in the UIKit SDK.

@nuno-vieira nuno-vieira transferred this issue from GetStream/stream-chat-swift Mar 14, 2024
@borutlatecheckout
Copy link
Author

This is most likely true, but cannot confirm for UIKit. In swiftUI this is certainly not updating for me. I would say that there is an issue with the binding. But would like to get a feedback from @martinmitrevski. Thanks @nuno-vieira for you assistance.

@martinmitrevski
Copy link
Contributor

@borutlatecheckout the viewModel.userFirstName and the ChatViewFactory is something we don't have in the SDK, should be in your app. Can you share how are you using it and when do you update that property?

@borutlatecheckout
Copy link
Author

You can ignore userFirstName since it is only used for the system chat message. For all other messages we read name and picture from the message.author.

ChatViewFactory looks like this:

final class ChatViewFactory: ViewFactory {
  typealias ActionHandler = GenericHandler<Action>
  @Injected(\.chatClient) public var chatClient
  var name: String?
  var action: ActionHandler?

  // custom message view
  func makeMessageContainerView(
    channel: ChatChannel, message: ChatMessage, width: CGFloat?, showsAllInfo: Bool,
    isInThread: Bool, scrolledId: Binding<String?>, quotedMessage: Binding<ChatMessage?>,
    onLongPress: @escaping (MessageDisplayInfo) -> Void, isLast: Bool
  ) -> some View {
    ChatMessageView(
      message: message,
      name: name ?? "User",
      showsAllInfo: showsAllInfo,
      action: action
    )
  }
}

And this is ChatMessageView:

struct ChatMessageView: View {
  let message: ChatMessage
  /// Name is only used for the initial/welcome message created on the BE.
  let name: String
  let showsAllInfo: Bool
  var action: ActionHandler?
  
  var body: some View {
    if message.isWelcome {
      ChatWelcomeView(date: message.createdAt, name: name)
    } else {
      regularMessage
    }
  }
}

I would assume I'm doing all things correctly. If I add a reaction, the message will update. So I suppose name and picture should change as well when a update profile.

@martinmitrevski
Copy link
Contributor

Thanks, was able to reproduce this. We will look into it and let you know when we have an update.

@borutlatecheckout
Copy link
Author

@martinmitrevski any update on this one?

@martinmitrevski
Copy link
Contributor

Hey @borutlatecheckout, not yet - we have higher priority items at the moment.

@borutlatecheckout
Copy link
Author

This issue is also present when I add url to message. message.linkAttachments is empty until I reload the chat.

@laevandus laevandus added the bug Something isn't working label Jun 12, 2024
@martinmitrevski
Copy link
Contributor

Hey @borutlatecheckout,

This is fixed in 4.59.0. Thanks for your patience.

Best, Martin

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

4 participants