Search code examples
reactjsreact-hooksjsxgetstream-io

How to make a user able to join a channel using the channel's ID with getstream-io


I'm making this app where I'm using stream API (getstream-io). It's my first time using an API and I'm trying to find my way through this knowledge.

So, in my app is a two player game with a spectator. The spectator is the one who creates the game.

When you create a game, you make a call to the API to create a channel (to host the game). I used "messaging" type for it since the tutorial I'm following (doing a tic tac toe, that's kind of close) uses it so I figured it should be for me too.

You then have a GameID which is a 6 digit number which also serve as the channel's ID.

I want the two players to be able to join this channel/game, only with the game ID.

Here's what I have for now:

CreateGame.jsx

import React, { useState } from "react";
import { useChatContext, Channel } from "stream-chat-react";

import Split_or_Steal from "./Split_or_steal";
import Cookies from "universal-cookie";

function getRandomInt(max) {
  return Math.floor(Math.random() * max);
}

function CreateGame() {
  const cookies = new Cookies();
  const [gameID, setGameID] = useState("");
  const { client } = useChatContext();
  const [channel, setChannel] = useState(null);
  const createChannel = async () => {
    const gameID=getRandomInt(1000000)
    const newChannel = client.channel('messaging', gameID , {
      members: [cookies.get("userId")],
      session: 3,
      show: false,
      player1_input: null,
      player2_input: null
    });

    await newChannel.watch();
    setChannel(newChannel);
  };
  return (
    <>
      {channel ? (
        <Channel channel={channel}>
          <Split_or_Steal channel={channel} setChannel={setChannel}/>
        </Channel>
      ) : (
        <div className="">
          <button className=" w-52 h-24 border rounded-md bg-white text-black text-bold text-4xl hover:bg-blue-600 hover:text-white" onClick={createChannel}> CREATE </button>
        </div>
      )}
    </>
  );
}

export default CreateGame;

JoinGame.jsx

import React, { useState } from "react";
import { useChatContext, Channel } from "stream-chat-react";

import Split_or_Steal from "./Split_or_steal";
import Cookies from "universal-cookie";


function JoinGame() {
  const cookies = new Cookies();
  const [gameID, setGameID] = useState("");
  const { client } = useChatContext();
  const [channel, setChannel] = useState(null);

  const joinChannel = async () => 
    {
    
        const filter = { type: 'messaging', id: gameID };
        const sort = [{ last_message_at: -1 }];
        const channels = await client.queryChannels(filter, sort, {
            watch: true, // this is the default
            state: true,
        });
        if (channels.length ===0 ){
            alert("channel not found");
            return;
        }
        const joinedChannel=channels[0];
        await joinedChannel.watch();
        await joinedChannel.addMembers([cookies.get("userId")]);
        setChannel(joinedChannel);
        console.log("joined channel")
    };


  return (
    <>
      {channel ? (
        <Channel channel={channel}>
          <Split_or_Steal channel={channel} setChannel={setChannel}/>
        </Channel>
      ) : (
        <div className="">
          <h4>Join Game</h4>
          <input
            placeholder="Game ID"
            onChange={(event) => {
              setGameID(event.target.value);
            }}
          />
          <button onClick={joinChannel}> Join </button>
        </div>
      )}
    </>
  );
}

export default JoinGame;

It's actually kinda working as expected, I am able to find the channel with the gameID, and even join it, ONLY WITH THE ACCOUNT WHO CREATED IT.

That's the issue, when joining with an other account, you get an error saying this:

Uncaught (in promise) Error: StreamChat error code 70: QueryChannels failed with error: "1 channels match your query but cannot be returned because you don't have access to them. Did you forget to include {members: $in: ["fec7bc90-260e-41c4-bef1-1dbe695e082b"]}?"

So basically, the user cannot add himself to the channel. Any Idea how to fix this?

TLDR: user don't have the rights to add themselves to the channels!


Solution

  • The error happening is exactly what you mentioned: the user doesn't have the right to add themselves to channels.

    Per default, users will have the role of user. They will lack permission to update channel members on random channels, which is the default due to different reasons.

    How to fix this?

    1. go to the dashboard and select your project
    2. go to Roles and Permissions
    3. hit the Edit button at the top
    4. for Role select User and for Scope select Messaging
    5. in the search field enter update channel members
    6. activate the checkbox of the permission called Update Channel Members
    7. hit Save

    Feel free to reach out if that doesn't fix your issue! Also keep in mind that users will now be able to enter every channel, so you might want to add a custom mechanism for users to limit the channels they are allowed to join - if necessary.