📴

Flutter + FirebaseでOFF LINE対応

2023/12/29に公開

対象者

  • Firebaseのオフ・ライン対応に興味ある.
  • Flutter, Firebaseで開発経験がある人

やること/やらないこと

やること:
オフ・ライン対応なるものを公式ドキュメントを見て私がやってみたので、真似してみてね。
https://firebase.google.com/docs/firestore/manage-data/enable-offline?hl=ja

やらないこと:
これで本当に機能してるのかな〜と疑問に思うところがありつつやってみたところ。

プロジェクトの説明

WIFIをONにしてる状態と、OFFにしてる状態で動作検証はしてみました。iOSAndroid両方で動作検証しております。

👀これでキャッシュができるらしい?

キャッシュ サイズを構成する

永続性が有効になっている場合、Cloud Firestore は、オフライン アクセスを行うために、バックエンドから受信したすべてのドキュメントをキャッシュします。Cloud Firestore ではキャッシュ サイズに対し、デフォルトのしきい値を設定しています。デフォルトを超えると、Cloud Firestore は、定期的に古い未使用のドキュメントをクリーンアップしようとします。キャッシュ サイズのしきい値を変更するか、クリーンアップ プロセスを完全に無効にすることもできます。

db.settings = const Settings(
  persistenceEnabled: true,
  cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
);

こちらがDEMOアプリのコード:

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class CityView extends StatefulWidget {
  const CityView({super.key});

  
  _CityViewState createState() => _CityViewState();
}

class _CityViewState extends State<CityView> {
  // Firebaseをインスタンス化
  final FirebaseFirestore db = FirebaseFirestore.instance;
  // オフライン対応のために、データを保持するリストを定義
  List<DocumentSnapshot> cityList = [];
  // ページが表示された時に、データを取得する
  
  void initState() {
    super.initState();
    enablePersistence();
    fetchData();
  }
  // enablePersistenceメソッドは、オフライン対応のために必要な設定を行う
  void enablePersistence() async {
    db.settings = const Settings(
      persistenceEnabled: true,
      cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
    );
  }
  // fetchDataメソッドは、データを取得する。whereで、stateがCAのものを取得する
  void fetchData() {
    db
        .collection("cities")
        .where("state", isEqualTo: "CA")
        .snapshots(includeMetadataChanges: true)
        .listen((querySnapshot) {
      setState(() {
        // データを取得したら、cityListに格納する
        cityList = querySnapshot.docs;
      });
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("OFF LINE 対応")),
      // ListView.builderで、cityListのデータを表示する
      body: ListView.builder(
        itemCount: cityList.length,
        itemBuilder: (context, index) {
          final city = (cityList[index].data() as Map<String, dynamic>);
          return ListTile(
            title: Text(city["name"]),
            subtitle: Text(city["state"]),
          );
        },
      ),
    );
  }
}

main.dartimportしてビルドしてみてください:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:offline_app/chat_view.dart';
import 'package:offline_app/firebase_options.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const CityView(),
    );
  }
}

ビルドするとこんな感じです:

WIFIをOFFにしてみた:

iOS:

Android:

感想

今回は、公式ドキュメントを参考にしつつFlutter + Firebaseでオフライン対応をしてみました。自分のアウトプットのために記事を書きましたが、誰かのお役立つと嬉しいです。

Discussion