コガネブログ

平日更新を目標に Unity や C#、Visual Studio、ReSharper などのゲーム開発アレコレを書いていきます

【Unity】FirestoreException: Failed to get document from cache.

はじめに

using Firebase.Firestore;
using UnityEngine;

public class Example : MonoBehaviour
{
    private async void Start()
    {
        var firestore = FirebaseFirestore.DefaultInstance;

        var documentReference = firestore
                .Collection( "users" )
                .Document( "players" )
            ;

        var snapshot = await documentReference.GetSnapshotAsync( Source.Cache );

        var dictionary = snapshot.ToDictionary();
    }
}

まだサーバーから取得していないデータを
DocumentReference.GetSnapshotAsync( Source.Cache ) で取得しようとすると

FirestoreException: Failed to get document from cache. 
(However, this document may exist on the server. 
Run again without setting source to FirestoreSourceCache 
to attempt to retrieve the document 

端末にデータのキャッシュが存在しないという旨の例外が発生する

using Firebase.Firestore;
using UnityEngine;

public class Example : MonoBehaviour
{
    private async void Start()
    {
        var firestore = FirebaseFirestore.DefaultInstance;

        var documentReference = firestore
                .Collection( "users" )
                .Document( "players" )
            ;

        var snapshot = await documentReference.GetSnapshotAsync();

        var dictionary = snapshot.ToDictionary();
    }
}

上記のように引数を省略すれば、サーバーからデータを取得するが、

FirestoreException: Failed to get document because the client is offline.

オフラインの場合は上記の例外が発生してしまうため、
オフラインでも動作するアプリを実装している場合に支障をきたしてしまう

解決方法

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

public class Example : MonoBehaviour
{
    private async void Start()
    {
        var firestore = FirebaseFirestore.DefaultInstance;

        var documentReference = firestore
                .Collection( "users" )
                .Document( "players" )
            ;

        var dictionary = new Dictionary<string, object>();

        try
        {
            var snapshot = await documentReference.GetSnapshotAsync( Source.Cache );
            dictionary = snapshot.ToDictionary();
        }
        catch ( FirestoreException )
        {
        }
    }
}

端末にデータのキャッシュが存在しない場合は
初期値を使用する設計で問題なければ
try ~ catchFirestoreException を握りつぶせば良い