はじめに
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}" ); } } }
オフラインの状態でまだ端末キャッシュされていないデータを
DocumentReference.GetSnapshotAsync
で取得しようとすると
FirestoreException: Failed to get document because the client is offline.
サーバーからデータを取得しようとして上記の例外が発生する
解決方法
using System.Collections.Generic; 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" ) ; // パブリック DNS に ping を実行することでオンライかどうかを確認 var isOnline = await instance.IsOnlineAsync( 5 ); // オンラインならサーバーからデータを取得、 // オフラインなら端末のキャッシュからデータを取得することで // オフラインの時にサーバーにデータを取得しにいかないようにする var source = isOnline ? Source.Default : Source.Cache; // オフラインかつまだ端末にデータのキャッシュが存在しない場合は // try ~ catch で例外を握りつぶして初期値を使用 var dictionary = new Dictionary<string, object>(); try { var snapshot = await documentReference.GetSnapshotAsync( source ); dictionary = snapshot.ToDictionary(); } catch ( FirestoreException ) { } foreach ( var (key, value) in dictionary ) { Debug.Log( $"{key}: {value}" ); } } }
上記のようなコードにすることで
オフラインかつまだ端末にデータのキャッシュが存在しない場合でも
例外が発生せずにアプリが動作するようになる