Skip to content

bug: client.create_token returning a token but silently failing to create a user #133

@jahseng-lee

Description

@jahseng-lee

Describe the bug

I've got code which, on visiting the "messenger" page for the first time, attempts to create a user and add them to a default list of channels.
I create a token using client.create_token, then attempt to add the user to a few channels.

However, I'm getting the exception

StreamChat::StreamAPIException (StreamChat error code 4: UpdateChannel failed with error: "The following users are involved in channel update operation, but don't exist: [94461a35e0a73734438dba5ba10bbb74]. Please create the user objects before setting up the channel.")

client.create_token returns a 200 success and also returns a token.
The only exception I get is when I consequently try to add the user, using my manually generated user_id, to channels.

This was working yesterday - my code around user creation doesn't seem to have changed.

To Reproduce

  1. Create a user using client.create_token(id) (I'm using id = SecureRandom.hex(16))
  2. Attempt to add user using channel.add_members([id])

Expected behavior

The create_token endpoint should:

  1. create a user if params are valid (which in this case they are); AND
  2. return an error if params are invalid OR the server is experience issues, so error handling can be handled

Package version

stream-chat-react: 10.14.0
stream-chat-css: 3.13.0

Desktop (please complete the following information):

OS: MacOS Ventura 13.2
Browser: Chrome
Version: 118.0.5993.70

Additional context

require "securerandom"

class ChatsController < ApplicationController
  # ...

  def show
    # NOTE: I've checked this ENV vars are set correctly
    if (ENV["STREAM_API_KEY"] && ENV["STREAM_API_SECRET"]).present?
      if current_user.stream_user_id.nil?
        @stream_user_id = SecureRandom.hex(16)
        # NOTE: the line below fails silently
        @stream_user_token = StreamChatClient.create_stream_user(
          id: @stream_user_id
        )

        current_user.update!(
          stream_user_id: @stream_user_id,
          stream_user_token: @stream_user_token
        )
      else
        @stream_user_id = current_user.stream_user_id
        @stream_user_token = current_user.stream_user_token
      end

      add_current_user_to_channels
    else
      # ...
    end
  end

  private

  def add_current_user_to_channels
    [
      { type: "messaging", id: "general" },
      { type: "messaging", id: "feedback-and-requests" },
      { type: "messaging", id: "bugs" },
    ].each do |channel|
      channel = StreamChatClient.get_channel(
        type: channel[:type],
        channel_id: channel[:id],
      )
      unless StreamChatClient.channel_include?(
          channel: channel,
          user_id: current_user.stream_user_id
      )
        StreamChatClient.add_member(
          channel: channel,
          user_id: current_user.stream_user_id
        )
      end
    end
  end
end

My StreamChatClient class:

require "stream-chat"

class StreamChatClient
  def self.add_member(channel:, user_id:)
    channel.add_members([user_id])
  end

  def self.channel_include?(channel:, user_id:)
    members = channel.query_members()["members"]
    members.map{ |member| member["user_id"] }.include?(user_id)
  end

  def self.get_channel(type:, channel_id:)
    client.channel(type, channel_id: channel_id)
  end

  def self.create_stream_user(id:)
    client.create_token(id)
  end

  private

  def self.client
    StreamChat::Client.new(
      api_key=ENV["STREAM_API_KEY"],
      api_secret=ENV["STREAM_API_SECRET"]
    )
  end
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions