v0.23.0 · Unity 6.3 LTS (6000.3) · pre-release

Unity Firebase Toolkit documentation.

The ten-minute path, the errors buyers hit first, and what is verified on every platform. The full reference ships in the package under Documentation~.

Back to the Unity Firebase Toolkit overview

Configure (2 minutes)

Configure, sign in, save, and read a leaderboard, then pick the systems you need. Everything below runs on any platform the toolkit supports, including WebGL. Minimum editor: Unity 6.3 LTS (6000.3).

  1. Open the Setup Wizard: Tools → ShipIt → Firebase Toolkit → Setup Wizard.
  2. Paste your project credentials: the Web API key and Project ID from Firebase console → Project settings → General. Press Test Connection, which validates the key and echoes the project it belongs to, then Save. This writes Assets/Resources/ShipIt/FirebaseSettings.asset.
  3. Enable sign-in methods: in Firebase console → Authentication → Sign-in method, enable Anonymous (guest play) and/or Email/Password.
  4. Publish a rules pack: toolkit window → Rules Packs → game_basics.rules. Cloud saves and scores are refused until their rules exist; default-deny is correct behaviour, not a bug.

Add moderation.rules and lobbies.rules when those features are used; each of the seven packs documents what it protects.

The Web API key is public by design. Authorization lives in Security Rules (and App Check), never in key secrecy.

Initialize and sign in

// once, at startup (the Firebase Bootstrap component can do this for you)
FirebaseClient.InitializeFromResources();

var auth = FirebaseClient.Instance.Auth;

// guest: enable Anonymous in the console first
var session = await auth.SignInAnonymouslyAsync();

// or email/password
var session = await auth.SignInWithEmailAsync(email, password);

Sessions persist and refresh automatically. Server failures arrive as FirebaseAuthException with .ServerCode (EMAIL_EXISTS, INVALID_LOGIN_CREDENTIALS, …). Upgrade guests with LinkEmailPasswordAsync: the uid stays the same, so progress survives the device.

Cloud saves

[Serializable] public class SaveData { public int level; public string hero; }

await FirebaseClient.Instance.CloudSave
    .SaveAsync("slot1",
        new SaveData { level = 3, hero = "Ada" });

var state = await FirebaseClient.Instance.CloudSave
    .LoadAsync<SaveData>("slot1");

Enable Offline Cache in settings and writes made while disconnected are queued durably and replayed on reconnect.

Leaderboard

await FirebaseClient.Instance.Leaderboard
    .SubmitScoreAsync(score);

var top = await FirebaseClient.Instance.Leaderboard
    .GetTopScoresAsync(10);

Personal-best semantics: a lower score never overwrites a higher one, and the shipped rules enforce the same server-side.

Check it in the editor: open the Collection Browser, which reads exactly what a signed-out client sees, then the Data Browser or Query Console for anything else.

Before you ship: move trust server-side

Startup code is client code. Before shipping anything with value, move currency grants and spends, score validation, IAP receipt checks and mail claims into Cloud Functions. Function Templates ships eight deployable templates for exactly these, and its validatePurchase template verifies receipts against Google Play and the App Store server-side rather than trusting the client.

Then run the Pentest screen against your project: it sweeps as an anonymous caller and reports what your rules actually expose.

Auth errors

Every server error the toolkit surfaces, mapped to meaning and fix. All exceptions carry the raw server message; typed subclasses add context. Auth errors arrive on FirebaseAuthException.ServerCode.

ServerCodeMeaningFix
EMAIL_EXISTSAddress already registeredSign in instead, or send a password reset
INVALID_LOGIN_CREDENTIALS / INVALID_PASSWORD / EMAIL_NOT_FOUNDWrong email or passwordCheck credentials; legacy projects may return the older codes
INVALID_EMAILMalformed addressValidate before submit
USER_DISABLEDAccount disabled in the consoleConsole → Authentication → Users
WEAK_PASSWORDFewer than 6 charactersEnforce length client-side too
TOO_MANY_ATTEMPTS_TRY_LATERDevice throttledBack off; minutes, not seconds
OPERATION_NOT_ALLOWED / PASSWORD_LOGIN_DISABLEDProvider disabledEnable it in Console → Authentication → Sign-in method
INVALID_ID_TOKENSession token expired or revokedRestore or sign in again; auto-refresh normally handles this
ADMIN_ONLY_OPERATIONRestricted operationNeeds the Admin SDK, server-side

Firestore errors

Firestore failures arrive on FirebaseFirestoreException.Status.

StatusMeaningFix
PERMISSION_DENIEDSecurity Rules rejected the callCheck the rules in the console or the Rules Simulator; signed-out callers need public read rules
NOT_FOUNDDocument absentCatch and treat as create-or-default
FAILED_PRECONDITIONMissing composite index (queries) or a failed preconditionThe message links to the index-creation URL; open it
RESOURCE_EXHAUSTEDQuota or billing limitCheck usage; the offline queue pauses on this status
ABORTEDTransaction contentionRunInTransactionAsync retries automatically; raise maxAttempts for hot paths
UNAVAILABLETransient server or network issueThe retry policy already retried; surface it as "try again"
UNAUTHENTICATEDToken missing or expired and no session restoredSign in first

Storage errors

Storage failures arrive as FirebaseStorageException.

SymptomCauseFix
403 on upload or readRules deny the path or callerThe game_basics pack covers saves and scores; add rules for your own folders
404 on downloadObject absent, or the wrong bucketCheck the bucket in the Setup Wizard and the object path's case
402, or a billing-flavoured 403The project is not on the Blaze planCloud Storage for Firebase needs Blaze; Spark projects have had no bucket access since 2026-02-03
The default bucket follows the project's creation date: PROJECT_ID.firebasestorage.app for projects created since September 2024, and PROJECT_ID.appspot.com for older ones. Set the exact name shown in Firebase console → Storage.

Functions errors

Callable failures arrive as FirebaseFunctionsException, with the HttpsError status and details attached.

SymptomFix
401 or 403 on a callThe function requires auth: sign in before calling, and check its allowUnauthenticated configuration

The package's Documentation~/Troubleshooting.md carries more tables: vector search, moderation and lobby symptoms, the remaining Functions codes (404, INVALID_ARGUMENT), and the download-token case for public Storage URLs.

Top gotchas

  1. WebGL: everything here is plain HTTP, but you still cannot open sockets. Realtime Database streaming uses SSE over HTTP. Do not import the official Firebase Unity SDK alongside this toolkit.
  2. "Setup incomplete" at runtime: the settings asset is not at Assets/Resources/ShipIt/FirebaseSettings.asset. Create it from the Setup Wizard.
  3. Rules debugging: the Collection Browser shows exactly what an anonymous caller sees. If a call works there but fails in-game, your token or provider is the difference; check the sign-in state.
  4. Offline writes: enable Offline Cache in settings; deferred documents come back flagged DeferredLocally. Transactions never queue; they are always live.
  5. Token expiry mid-session: handled by SecureToken refresh; GetValidIdTokenAsync() collapses concurrent refreshes into one.
  6. WebGL hosting: if the loading bar hangs at 90%, the host is serving the .gz build files without Content-Encoding: gzip. Enable Decompression Fallback in the WebGL Player Settings, or configure the host to send the header.
  7. Aggregations read as zero: fixed in 0.13.0, where the parser read the response one level too high. AggregateAsync now reads both the documented and the flattened shapes.

Platform support

PlatformStatusNotes
Windows / macOS / Linux (Mono and IL2CPP)SupportedFull feature set
Android / iOS (IL2CPP)SupportedFull feature set; link.xml guards reflection-materialized types
WebGLSupportedThe reason this toolkit exists; see WebGL specifics

Scripting backend: pure C# over UnityWebRequest. No native plugins, no JavaScript bridges, no Reflection.Emit, so it is safe for IL2CPP/AOT and for the WebAssembly sandbox. Build proofs exist for WebGL and Windows IL2CPP; see Verified builds.

WebGL specifics

  • All networking uses UnityWebRequest, the only HTTP stack available in the browser sandbox. Realtime listeners that need raw sockets (Firestore gRPC streams) are out of scope.
  • Session persistence and the offline mutation queue go through PlayerPrefs, which Unity maps to IndexedDB on the web. Clearing browser data clears them, by design of the platform.
  • CORS: Firebase's googleapis endpoints send permissive headers for API calls, so hosting your build on any origin works without extra configuration.
  • OAuth popup or redirect sign-in and the phone reCAPTCHA widget need a JavaScript bridge, which the toolkit deliberately does not have. Use email and password, anonymous, custom tokens, or a provider token obtained natively.
  • Builds stay lean: the toolkit adds only C# code, and the engine's own HTTP client does the transport.

Known limitations

LimitationReasonWorkaround
No Firestore realtime listenersUpstream realtime is gRPC-only; REST has no documented streamUse the Realtime Database (RtdbService.Listen), which streams over SSE, or poll Firestore queries
No Query ExplainIt accepts only IAM server credentials, and service accounts must never ship in a clientRun it from server-side tooling
Vector search needs an indexFirestore requires a vectorConfig index for findNearestThe Vector Search screen exports the exact firestore.indexes.json snippet
App Check uses the debug providerNative attestation (Play Integrity, DeviceCheck) needs platform pluginsImplement IAppCheckTokenProvider; the debug provider works while enforcement is off
Resumable upload chunk size is fixed per callSimplicityPass a larger chunkSize for big files
Rules Simulator probes real pathsThe REST surface cannot read a project's rulesRead its verdicts as evidence from real allow and deny responses, not as a rules parser

Verified builds

The v0.23.0 release run on Unity 6000.3.11f1, September 20, 2026. The build checks use the Panel Tour demo scene.

CheckHowResult
EditMode suiteUnity Test Runner, or CI testMode: editmode776 passed, 0 failed
PlayMode smoke suiteUnity Test Runner, headless; demo boot path and drop-in panel construction17 passed
WebGL buildBatch build of the Panel Tour scene0 errors, 0 warnings, about 10.1 MB
WebGL runtime bootci/webgl-proof.cjs in headless ChromiumPass, no page errors
Windows IL2CPP buildThe same scene with the IL2CPP scripting backend0 errors, 0 warnings
Unity.exe -batchmode -nographics -quit -projectPath <project> \
  -executeMethod ShipIt.Firebase.EditorTools.WebGLVerification.BuildDemo

Unity.exe -batchmode -nographics -quit -projectPath <project> \
  -executeMethod ShipIt.Firebase.EditorTools.Il2CppVerification.BuildDemo

The WebGL boot check matters most: the official Firebase Unity SDK's documented failure for this combination is a crash on startup, and a boot test catches exactly that class of defect.

Support

Email shipit.unity@gmail.com with your Unity version, the toolkit version, the target platform and the relevant log lines. The complete engineering changelog ships inside the package as CHANGELOG.md; highlights are on the release notes page.