How to Set Up Cloud Saves for a Mobile Game Using Firebase

How to Set Up Cloud Saves for a Mobile Game Using Firebase

by | Aug 4, 2026 | Uncategorized | 0 comments

Losing player progress is one of the fastest ways to get a 1-star review on the App Store or Google Play. If you’re an indie developer shipping a mobile game in 2026, implementing cloud saves for your mobile game is no longer optional, it’s expected. Players switch devices, reinstall apps, and demand that their progress follows them everywhere.

In this practical tutorial, we’ll walk through how to build a robust cross-device cloud save system using Firebase Firestore in Unity, targeting both iOS and Android. We’ll also tackle the trickiest part: resolving conflicts between local and cloud data.

Why Firebase Firestore for Cloud Saves in Mobile Games?

You have plenty of options for cloud saves: Google Play Games Services, Apple’s Game Center, Epic Online Services, or building your own backend. Here’s why Firebase Firestore is a strong pick for indie devs:

  • Cross-platform by default: One codebase works on iOS and Android without duplicating logic.
  • Generous free tier: Spark plan covers most indie games until they scale.
  • Real-time sync: Firestore pushes updates when data changes, useful for multi-device players.
  • Simple authentication: Firebase Auth handles anonymous, Google, and Apple sign-in out of the box.
  • Offline support: Built-in local caching for offline play.

Firebase vs Other Cloud Save Options

Solution Cross-platform Conflict Handling Cost
Firebase Firestore Yes Custom (flexible) Free tier + pay as you go
Google Play Games Services Android only Built-in Free
Apple Game Center iOS only Built-in Free
Epic Online Services Yes Built-in Free
mobile game cloud save

Step 1: Set Up Firebase in Your Unity Project

  1. Go to the Firebase Console and create a new project.
  2. Add both an iOS app (with your bundle ID) and an Android app (with your package name).
  3. Download the GoogleService-Info.plist (iOS) and google-services.json (Android) and drop them into Assets/.
  4. Download the Firebase Unity SDK and import these packages:
    • FirebaseAuth.unitypackage
    • FirebaseFirestore.unitypackage
  5. In Player Settings, make sure iOS is set to a minimum of iOS 13 and Android minimum API level 24.

Step 2: Authenticate the Player

Before saving anything to the cloud, we need a stable user ID. Anonymous auth is the fastest way to onboard players without forcing a login screen, and you can upgrade to Google/Apple sign-in later.

using Firebase.Auth;
using System.Threading.Tasks;
using UnityEngine;

public class AuthManager : MonoBehaviour
{
    private FirebaseAuth auth;
    public string UserId { get; private set; }

    async void Start()
    {
        auth = FirebaseAuth.DefaultInstance;
        await SignInAnonymously();
    }

    private async Task SignInAnonymously()
    {
        try
        {
            var result = await auth.SignInAnonymouslyAsync();
            UserId = result.User.UserId;
            Debug.Log($"Signed in as: {UserId}");
        }
        catch (System.Exception e)
        {
            Debug.LogError($"Auth failed: {e.Message}");
        }
    }
}

Step 3: Design Your Save Data Model

Keep your save schema flat and versioned. This makes migrations painless when you add new features later.

[System.Serializable]
public class PlayerSave
{
    public int schemaVersion = 1;
    public long lastUpdatedUnix;
    public string deviceId;
    public int level;
    public int coins;
    public int gems;
    public string[] unlockedItems;
}

The two critical fields for conflict resolution are lastUpdatedUnix and deviceId. We’ll use them shortly.

mobile game cloud save

Step 4: Write to Firestore

using Firebase.Firestore;
using Firebase.Extensions;
using UnityEngine;

public class CloudSaveManager : MonoBehaviour
{
    private FirebaseFirestore db;

    void Start()
    {
        db = FirebaseFirestore.DefaultInstance;
    }

    public void SaveToCloud(string userId, PlayerSave save)
    {
        save.lastUpdatedUnix = System.DateTimeOffset.UtcNow.ToUnixTimeSeconds();
        save.deviceId = SystemInfo.deviceUniqueIdentifier;

        DocumentReference docRef = db.Collection("saves").Document(userId);
        docRef.SetAsync(save).ContinueWithOnMainThread(task =>
        {
            if (task.IsCompletedSuccessfully)
                Debug.Log("Cloud save successful.");
            else
                Debug.LogError("Cloud save failed: " + task.Exception);
        });
    }
}

Step 5: Load from Firestore

public void LoadFromCloud(string userId, System.Action<PlayerSave> onLoaded)
{
    DocumentReference docRef = db.Collection("saves").Document(userId);
    docRef.GetSnapshotAsync().ContinueWithOnMainThread(task =>
    {
        if (task.IsCompletedSuccessfully && task.Result.Exists)
        {
            PlayerSave cloudSave = task.Result.ConvertTo<PlayerSave>();
            onLoaded?.Invoke(cloudSave);
        }
        else
        {
            onLoaded?.Invoke(null);
        }
    });
}

Step 6: Handling Conflicts Between Local and Cloud Saves

This is where most indie developers get burned. A player opens the game on device B, plays for two hours, then opens device A which still has an older local save. Which one wins?

The 3-Rule Conflict Resolution Strategy

  1. Same device ID: Trust the newer timestamp automatically.
  2. Different device, cloud is newer: Prompt the player, defaulting to cloud.
  3. Different device, local is newer: Prompt the player, defaulting to local, but ALWAYS show what they’d lose.
public enum ConflictResolution { UseLocal, UseCloud, AskUser }

public ConflictResolution ResolveConflict(PlayerSave local, PlayerSave cloud)
{
    if (local == null) return ConflictResolution.UseCloud;
    if (cloud == null) return ConflictResolution.UseLocal;

    bool sameDevice = local.deviceId == cloud.deviceId;
    bool cloudNewer = cloud.lastUpdatedUnix > local.lastUpdatedUnix;

    if (sameDevice)
        return cloudNewer ? ConflictResolution.UseCloud : ConflictResolution.UseLocal;

    long diff = System.Math.Abs(cloud.lastUpdatedUnix - local.lastUpdatedUnix);
    if (diff < 60) return ConflictResolution.UseCloud;

    return ConflictResolution.AskUser;
}

When you prompt the user, show a clear comparison:

Field This Device Cloud
Level 12 17
Coins 450 1,220
Last played 3 days ago 2 hours ago
mobile game cloud save

Step 7: Platform-Specific Considerations

Android

  • Enable SHA-1 fingerprint for your keystore in the Firebase Console (required for Google Sign-in later).
  • Add <uses-permission android:name="android.permission.INTERNET"/> if not already in your manifest.
  • Test on physical devices, emulators sometimes have issues with Google Play Services.

iOS

  • In Xcode, ensure the GoogleService-Info.plist is added to the target.
  • Set Bitcode to No, Firebase Unity SDK doesn’t support it.
  • If shipping to the EU, remember to declare Firebase in your App Privacy manifest (required since iOS 17).

Step 8: Firestore Security Rules

Never leave Firestore in test mode when you ship. Use these rules to ensure players can only read and write their own save:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /saves/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

Best Practices for Cloud Saves in Production

  • Save on lifecycle events: Trigger a cloud sync in OnApplicationPause and OnApplicationQuit.
  • Debounce writes: Don’t push every coin pickup, batch changes every 30 to 60 seconds.
  • Keep local saves as a fallback: Cloud can fail, PlayerPrefs or a JSON file should always exist.
  • Version your schema: When you add fields, write migration code before deserializing old saves.
  • Log conflicts: Send an analytics event when a user picks local over cloud, this helps you spot bugs.

FAQ

Can you use cloud storage for mobile games without a backend team?

Yes. Firebase Firestore is designed for solo devs and small teams. You don’t need to write server code, the SDK handles authentication, storage, and sync directly from Unity.

Will players lose progress if they get a new phone?

Not if you implement cloud saves correctly. As long as the player signs in with the same account (Google, Apple, or a linked anonymous account), Firestore will restore their save on the new device.

How much does Firebase Firestore cost for a mobile game?

The Spark (free) plan includes 50,000 reads, 20,000 writes, and 1 GB of storage per day. For most indie mobile games with under 10,000 daily active users, this is enough. Beyond that, Blaze pay-as-you-go is typically cents per day per thousand active users.

Should I use Firebase or Google Play Games Services for Android cloud saves?

If your game is Android-only, Google Play Games Services is free and integrates well. If you’re shipping on both iOS and Android, Firebase gives you one unified system, which is far easier to maintain.

How do I handle offline players?

Firestore has built-in offline persistence enabled by default in the Unity SDK. Writes made offline are queued and pushed automatically when the device reconnects. Always keep a local save file as a hard backup.

Wrapping Up

Implementing cloud saves for a mobile game with Firebase Firestore takes an afternoon to set up and pays off for the entire lifetime of your game. Players expect their progress to follow them, and giving them that experience translates directly into better reviews, higher retention, and fewer support tickets.

At Falanxia, we help studios ship polished mobile games with production-grade backends, analytics, and live-ops tooling. If you need help architecting your cloud save system or scaling it beyond the Firebase free tier, get in touch.