📑

Cloud Firestore と Flutter 2でユーザーがオンラインか判定する

2021/07/25に公開

1. はじめに

SlackDiscordなどのコミュニケーションアプリには、必ずと言っていいほどユーザーがオンラインでアクティブになっているか判定する機能(「プレゼンス」検出)があります。Cloud Firestoreで実装したいところですが、残念ながらサポートされていません(Cloud Firestore でプレゼンスを構築する)。しかし、Realtime DatabaseCloud Functionsを利用すれば、実装することが可能です。
今回はFlutter 2.0とCloud Firestore、 Cloud Functions、そしてRealtime Databaseを使用して、プレゼンスを構築していきます。

トップ ユーザーリスト

2. 設計

該当アプリの接続が切れた時に、Realtime DatabaseのonDisconnect()を呼び、Realtime Databaseのフィールドを更新します。
このフィールド更新がトリガーとなり、Cloud Functionsの関数が実行されます。この関数により、該当アプリの接続が切れたという情報がCloud Firestoreに書き込まれます。

3. 実装

事前準備

  1. Cloud FirestoreおよびRealtime Databaseのプロビジョニング
  2. 1の後、GoogleServices-info.plistおよびgoogle-service.jsonをアプリに追加
  1. パッケージの追加
    • cloud_firestore: ^2.4.0
    • firebase_auth: ^3.0.1
    • firebase_core: "^1.4.0"
    • firebase_database: ^7.1.2
    • flutter_riverpod: ^0.14.0+3

Flutter

プレゼンス構築に直接関わるコードのみ解説します。
それ以外のコードはGithubにて公開しました。
必要に応じて、GoogleServices-info.plistおよびgoogle-service.jsonを追加してください。
https://github.com/mafreud/online_presence_flutter2

アプリの状態を保存

Realtime Databaseにて、ユーザーのアプリの状態を更新するメソッドです。

Future<void> updateUserPresence(String uid) async {
  // プレゼンスをtrueに更新
  await _databaseReference.child(uid).update({'presence': true});

  // アプリの接続が切れ次第、プレゼンスをfalseに更新
  await _databaseReference
      .child(uid)
      .onDisconnect()
      .update({'presence': false});
}

Cloud Functions

Realtime Databaseへの書き込みでトリガーされる関数です。

exports.onUserStatusChange = functions.database
  .ref("/{uid}/presence")
  .onUpdate(async (change: any, context: any) => {
    // Realtime Databaseに書き込まれたデータを取得
    const isOnline = change.after.val();

    // DocumentReference
    const ref = firestore.doc(`users/${context.params.uid}`);
    console.log(`status: ${isOnline}`);

    // Firestoreの値を更新
    return ref.update({
      isOnline: isOnline,
      lastSeen: Date.now(),
    });
  });

4. 完成

アプリ→Realtime Database→(Cloud Functions)→Cloud Firestore
という順に更新されています。

アプリ Realtime Database Cloud Firestore

https://github.com/mafreud/online_presence_flutter2

5. 注意

今回の実装では次に挙げるような制限があります。本番環境で採用する際は十分注意してください。

Flutter

Cloud Functions

Realtime Database

Android

参考文献

https://firebase.google.com/docs/firestore/solutions/presence?hl=ja
https://blog.codemagic.io/user-presence-in-cloud-firestore-with-flutter/

Discussion