Cloud Firestore と Flutter 2でユーザーがオンラインか判定する
1. はじめに
SlackやDiscordなどのコミュニケーションアプリには、必ずと言っていいほどユーザーがオンラインでアクティブになっているか判定する機能(「プレゼンス」検出)があります。Cloud Firestoreで実装したいところですが、残念ながらサポートされていません(Cloud Firestore でプレゼンスを構築する)。しかし、Realtime DatabaseとCloud Functionsを利用すれば、実装することが可能です。
今回はFlutter 2.0とCloud Firestore、 Cloud Functions、そしてRealtime Databaseを使用して、プレゼンスを構築していきます。
トップ | ユーザーリスト |
---|---|
2. 設計
該当アプリの接続が切れた時に、Realtime DatabaseのonDisconnect()を呼び、Realtime Databaseのフィールドを更新します。
このフィールド更新がトリガーとなり、Cloud Functionsの関数が実行されます。この関数により、該当アプリの接続が切れたという情報がCloud Firestoreに書き込まれます。
3. 実装
事前準備
- Cloud FirestoreおよびRealtime Databaseのプロビジョニング
- 1の後、GoogleServices-info.plistおよびgoogle-service.jsonをアプリに追加
- パッケージの追加
- 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を追加してください。
アプリの状態を保存
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 |
---|---|---|
5. 注意
今回の実装では次に挙げるような制限があります。本番環境で採用する際は十分注意してください。
Flutter
Cloud Functions
Realtime Database
Android
参考文献
Discussion