Firebase 实时数据库按状态值计算活跃用户数
Posted
技术标签:
【中文标题】Firebase 实时数据库按状态值计算活跃用户数【英文标题】:Firebase Realtime database count active users by status value 【发布时间】:2022-01-09 01:29:22 【问题描述】:我有一项服务可以检测用户在 firebase 中在线、离开和离线时的存在情况。
presence.service.ts
import Injectable from "@angular/core";
import AngularFireAuth from "@angular/fire/auth";
import AngularFireDatabase from "@angular/fire/database";
import * as firebase from "firebase/app";
import tap, map, switchMap, first from "rxjs/operators";
import of from "rxjs";
import SuperUserService from "./../services/superuser.service";
@Injectable(
providedIn: "root",
)
export class PresenceService
constructor(
private afAuth: AngularFireAuth,
private db: AngularFireDatabase,
private superuser: SuperUserService
)
console.log("Verificação de status em execução");
this.setName();
this.updateOnUser().subscribe();
this.updateOnDisconnect().subscribe();
this.updateOnAway();
getPresence(uid: string)
return this.db.object(`status/$uid`).valueChanges();
getUser()
return this.afAuth.authState.pipe(first()).toPromise();
async setPresence(status: string)
const user = await this.getUser();
if (user)
return this.db.object(`status/$user.uid`).update(
status,
timestamp: this.timestamp,
);
async setName()
const user = await this.getUser();
if (user)
return this.db.object(`status/$user.uid`).update(
nome: this.superuser.user.displayName,
);
get timestamp()
return firebase.database.ServerValue.TIMESTAMP;
updateOnUser()
const connection = this.db
.object(".info/connected")
.valueChanges()
.pipe(map((connected) => (connected ? "online" : "offline")));
return this.afAuth.authState.pipe(
switchMap((user) => (user ? connection : of("offline"))),
tap((status) => this.setPresence(status))
);
updateOnDisconnect()
return this.afAuth.authState.pipe(
tap((user) =>
if (user)
return this.db
.object(`status/$user.uid`)
.query.ref.onDisconnect()
.update(
status: "offline",
timestamp: this.timestamp,
);
)
);
async signOut()
await this.setPresence("offline");
await this.afAuth.signOut();
updateOnAway()
document.onvisibilitychange = (e) =>
if (document.visibilityState === "hidden")
this.setPresence("away");
else
this.setPresence("online");
;
Firebase 路径
考虑到这一点,我想要实现一种方法来显示有多少用户是活跃的(在线和离开)例如:15 个活跃用户
我试过这个,但它只会让我知道是否存在
ref.child("status").orderByChild("status").equalTo("online")
.once("value",snapshot =>
if (snapshot.exists())
// if exist
);
【问题讨论】:
【参考方案1】:如果你想用你当前的数据结构显示在线用户的数量,你可以保持与之前相同的查询,然后use snapshot.numChildren()
来确定它返回的在线用户的数量。
如果您想使用当前数据结构显示在线和离线用户的计数,您可以:
对离线用户使用第二个查询,并使用与上述相同的方法来获取计数。
在 status
字段上使用不带条件的单次读取,然后计算应用程序代码中的各个节点:
ref.child("status")
.once("value",snapshot =>
let onlineCount=0, offlineCount=0;
snapshot.forEach((user) =>
const status = user.child("status").val();
if (status === "online) onlineCount++
else if (status === "offline) offlineCount++
else console.error(`Unexpected status '$status' for user $user.key`);
)
console.log(`Online: $onlineCount, Offline: $offlineCount`);
);
如果您阅读所有这些用户配置文件只是为了在您的应用中显示两个计数器,那么您会为您自己和您的用户浪费相当多的带宽(因此也就是金钱)。考虑将您希望在数据库本身中显示的实际计数存储起来,并在每个用户在线/离线时在 Cloud Functions 等工具中更新它们。
【讨论】:
以上是关于Firebase 实时数据库按状态值计算活跃用户数的主要内容,如果未能解决你的问题,请参考以下文章
使用 Flutter 和 Firebase 实现实时在线/离线状态
如何计算 Firebase 中的 MAU?我需要 BigQuery 吗?
Google Analytics“活跃用户”和 Firebase“活跃用户”有啥区别?