You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中从Firestore读取Map的实现方法:获取名为Statistics的Map数据

Reading Map Data (Statistics) from Firestore in Unity

Hey there! I’ve tackled this exact problem multiple times when building Unity games with Firestore, so let me break down the process clearly for you.

Prerequisites

First, make sure you’ve got the basics sorted:

  • The Firebase Firestore SDK is installed in your Unity project (via Package Manager or Firebase Console’s setup wizard).
  • Firebase is initialized correctly in your project (you should have the google-services.json file in your Assets folder for Android, or GoogleService-Info.plist for iOS).

Step 1: Define a C# Class for Your Statistics Map

The cleanest way to work with Firestore Maps is to map them to a strongly-typed C# class. This makes your code type-safe and way easier to maintain.

Let’s say your Statistics map in Firestore has fields like total_score (number), play_time_hours (number), and total_wins (number). Here’s how to define the corresponding class:

using UnityEngine;
using Firebase.Firestore;

[Serializable]
public class UserStatistics
{
    // Use [FirestoreProperty] if your Firestore keys use snake_case (common in Firestore)
    [FirestoreProperty("total_score")]
    public int TotalScore { get; set; }

    [FirestoreProperty("play_time_hours")]
    public float PlayTimeHours { get; set; }

    [FirestoreProperty("total_wins")]
    public int TotalWins { get; set; }

    // If your Firestore keys match the C# property names exactly (e.g., "TotalScore"),
    // you can skip the [FirestoreProperty] attribute entirely
}

Step 2: Fetch and Deserialize the Map Data

Firestore operations are asynchronous, so we’ll use async/await for clean code. Here’s a complete example of a MonoBehaviour that fetches the Statistics map:

using Firebase;
using Firebase.Firestore;
using UnityEngine;
using System.Threading.Tasks;
using System.Collections.Generic;

public class StatsReader : MonoBehaviour
{
    private FirebaseFirestore _firestoreDb;

    void Start()
    {
        // Initialize Firebase first
        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
        {
            if (task.Result == DependencyStatus.Available)
            {
                _firestoreDb = FirebaseFirestore.DefaultInstance;
                Debug.Log("Firebase ready to go!");
                // Fetch stats for a specific user (replace with your user ID logic)
                FetchUserStats("player_456");
            }
            else
            {
                Debug.LogError("Failed to initialize Firebase: " + task.Result);
            }
        });
    }

    private async void FetchUserStats(string userId)
    {
        try
        {
            // Get reference to the user's document (adjust collection/document paths to match your setup)
            DocumentReference userDoc = _firestoreDb.Collection("players").Document(userId);
            DocumentSnapshot snapshot = await userDoc.GetSnapshotAsync();

            if (snapshot.Exists)
            {
                // Method 1: Deserialize directly to your custom class (RECOMMENDED)
                UserStatistics stats = snapshot.GetValue<UserStatistics>("Statistics");
                if (stats != null)
                {
                    Debug.Log($"Loaded Stats: Score={stats.TotalScore}, Play Time={stats.PlayTimeHours}h, Wins={stats.TotalWins}");
                    // Use these stats in your game (e.g., update UI, save to player data)
                    UpdateGameUI(stats);
                }
                else
                {
                    Debug.LogWarning("Statistics field exists but couldn't be deserialized. Check field types!");
                }

                // Method 2: Read as a Dictionary (for dynamic/unknown map structures)
                Dictionary<string, object> statsDict = snapshot.GetValue<Dictionary<string, object>>("Statistics");
                if (statsDict != null)
                {
                    foreach (var entry in statsDict)
                    {
                        Debug.Log($"Stats Entry: {entry.Key} = {entry.Value}");
                    }
                }
            }
            else
            {
                Debug.LogError($"User document {userId} doesn't exist in Firestore!");
            }
        }
        catch (System.Exception ex)
        {
            Debug.LogError($"Error fetching stats: {ex.Message}");
        }
    }

    // Example method to update your game's UI with the stats
    private void UpdateGameUI(UserStatistics stats)
    {
        // Replace with your actual UI logic
        // scoreText.text = stats.TotalScore.ToString();
        // playTimeText.text = $"{stats.PlayTimeHours:F1}h";
    }
}

Key Notes & Troubleshooting

  • Field Type Matching: Make sure the data types in your C# class match exactly what’s stored in Firestore. For example, a Firestore Number can map to int, float, or double—but mismatches will cause deserialization failures.
  • Nested Maps: If your Statistics map contains other nested maps, just create nested C# classes and mirror the structure. Firestore will handle deserializing nested objects automatically.
  • Main Thread Updates: If you’re updating UI elements with the fetched stats, remember that Firestore callbacks run on a background thread. Use UnityMainThreadDispatcher (or wrap your UI code in UnityEngine.WaitForEndOfFrame) to switch back to the main thread.
  • Firestore Rules: Double-check your Firestore security rules to ensure your app has permission to read the document. If you get permission errors, adjust the rules temporarily for testing (but lock them down for production!).

内容的提问来源于stack exchange,提问作者MarlonDSC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:17:31