コガネブログ

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

【Unity】Firestore の DocumentReference.GetSnapshotAsync はオフラインの場合処理に時間がかかることがある

はじめに

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();

        foreach ( var (key, value) in dictionary )
        {
            Debug.Log( $"{key}: {value}" );
        }
    }
}

Firestore の DocumentReference.GetSnapshotAsync は
オフラインの場合処理に時間がかかることがある

解決方法

using Cysharp.Threading.Tasks;
using Firebase.Firestore;
using Kogane;
using UnityEngine;

public class Example : MonoBehaviour
{
    private async UniTaskVoid Start()
    {
        // https://github.com/baba-s/Kogane.InternetCheckerInstance
        var instance = new InternetCheckerInstance
        (
            "8.8.8.8", // Google Public DNS
            "8.8.4.4"  // Google Public DNS
        );

        var firestore = FirebaseFirestore.DefaultInstance;

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

        var isOnline = await instance.IsOnlineAsync( 5 );
        var source   = isOnline ? Source.Default : Source.Cache;
        var snapshot = await documentReference.GetSnapshotAsync( source );

        var dictionary = snapshot.ToDictionary();

        foreach ( var (key, value) in dictionary )
        {
            Debug.Log( $"{key}: {value}" );
        }
    }
}

パブリック DNS に ping を実行することで
インターネットに接続しているかどうかを確認し、
インターネットに接続している場合はサーバーからデータを取得、
オフラインの場合は端末が保持しているキャッシュからデータを取得するように
明示的に source 引数を指定することで処理がすぐ完了するようになる