If your browser game signs players in with Firebase, GameRelay can use those accounts directly: a signed-in player is the same player on every device, with their saves and leaderboard entries. It takes one dashboard setting and one line in connect, with no Cloud Function or server of your own, and it works on static hosts like itch.io.
1. Set up Firebase Authentication
- In the Firebase console, create a project and add a web app. Keep the config it shows.
- Under Authentication → Sign-in method, turn on the ways players sign in: Google, email and password, or others.
- Under Authentication → Settings → Authorized domains, add every site your game runs on. For itch.io that's
html-classic.itch.zone, where itch.io serves HTML games, as well asitch.io.
2. Tell GameRelay about your project
In the dashboard, open your game's Settings → Player sign-in, pick Firebase and paste your project id (Firebase console → Project settings → Project ID). While you're there, add your sites under Allowed origins: https://*.itch.zone for itch.io, and http://localhost for testing.
3. Connect with the player's ID token
Pass idToken to GameRelay.connect. Firebase's getIdToken() refreshes the token by itself, and the SDK calls it before every connect and reconnect. Signed out, it returns nothing, and the player joins as a guest. A complete page:
<button id="signin">Sign in with Google</button>
<button id="guest">Play as guest</button>
<p id="status"></p>
<script type="module">
// Use the version and config the Firebase console gives you (Project settings → Your apps).
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.12.0/firebase-app.js';
import { getAuth, GoogleAuthProvider, signInWithPopup, onAuthStateChanged } from 'https://www.gstatic.com/firebasejs/10.12.0/firebase-auth.js';
import { GameRelay } from 'https://gamerelay.io/sdk/v0/gamerelay.mjs';
const auth = getAuth(initializeApp({ apiKey: '…', authDomain: 'my-game.firebaseapp.com', projectId: 'my-game' }));
const status = document.getElementById('status');
// Ask once, then keep it. Name moderation checks it like anyone else's.
function playerName() {
let name = localStorage.getItem('name');
if (!name) {
name = prompt('Your name?')?.trim().slice(0, 24) || 'Player';
localStorage.setItem('name', name);
}
return name;
}
let started = false;
async function play() {
if (started) return; // signing in after starting as a guest keeps this game going
started = true;
const relay = await GameRelay.connect({
publicKey: 'gr_pub_…',
playerName: playerName(), // Firebase has no username: the game asks for one (below)
idToken: () => auth.currentUser?.getIdToken(), // signed out: null, so the player is a guest
});
status.textContent = relay.signedIn ? `Signed in as ${relay.playerName}` : 'Playing as a guest';
const room = await relay.joinOrCreate({ maxPlayers: 8 });
startGame(relay, room); // your game
}
// A popup, not a redirect: on itch.io the game runs in a frame, and a redirect would take it away.
document.getElementById('signin').onclick = () => signInWithPopup(auth, new GoogleAuthProvider());
document.getElementById('guest').onclick = play;
onAuthStateChanged(auth, (user) => user && play());
</script>relay.playerId is now the player's Firebase uid, on every device. Their saves (relay.storage) and leaderboard entries follow them, and so does a ban from a room.
4. Player names
Firebase has no username of its own, and GameRelay never shows the token's full name (for a Google account, that's the player's real name). So the name others see is the playerName your game passes, which your name moderation checks like anyone else's. Ask players for a name once and keep it, as above.
To choose names yourself (for a class, say), give each account a custom claim username with the script in the next step, and set Name claim to username. Every connect then starts with that name. Players can still rename themselves for a session with relay.setName(), so leave renaming out of your game.
5. Teachers and other roles
Custom claims are the Firebase way to mark an account. Set one with the Firebase Admin SDK, from a short script you run on your own computer:
// set-role.mjs: run once on your own computer, not in the game.
// Service account key: Firebase console → Project settings → Service accounts → Generate new private key.
import { initializeApp, cert } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
initializeApp({ credential: cert('./service-account.json') });
await getAuth().setCustomUserClaims(process.argv[2], { role: 'teacher' }); // node set-role.mjs <uid>The player gets the new claim when their token next refreshes. Your game can read its own player's role:
const { claims } = await auth.currentUser.getIdTokenResult(true); // true: fetch the new claims now
if (claims.role === 'teacher') showTeacherTools(); To have your backend see roles too, list role under Copied claims: GameRelay sends it with that player's webhook events.
6. Rooms for everyone
Rooms work as they do for anonymous players. Tags split them up, for example one world per student, then one room for all:
// Each student's world is a room with its own tag; everyone in world 3 lands in the same one.
const room = await relay.joinOrCreate({ tag: 'world-3', maxPlayers: 8 });
// And all together, in one shared room:
const hub = await relay.joinOrCreate({ tag: 'hub', maxPlayers: 16 });7. Test it
A signed-in player is one player everywhere, so the same Google account in two tabs is one player: the newer tab takes over. Test with two accounts, or one signed in and one guest. If you'd rather nobody joins without signing in, turn off Anonymous players in Player sign-in: then connect() rejects with sign_in_required for anyone signed out, so the game can show its sign-in button.
If something doesn't connect, the error says why:
- its issuer is …, expected …: the project id in Player sign-in isn't the game's Firebase project.
- This site isn't allowed to use this game's key: add the site under Allowed origins.
- A sign-in popup that won't open on itch.io: check the Authorized domains in Firebase.
For Supabase, Clerk, Auth0 and the other ways to sign players in, see Player accounts.
Try it
GameRelay has a free plan, no card needed. Get a public key, then follow the quickstart, or point your AI coding agent at llms.txt.