gpt4 book ai didi

android - 注销后实时数据库onDisconnect不执行

转载 作者:行者123 更新时间:2023-12-05 00:13:49 32 4
gpt4 key购买 nike

我已经实现了 Firebase 实时数据库存在系统,如 Firebase 官方文档中所示。我想让数据库安全,以便登录用户只能写入他们自己在数据库中的状态条目。因此,在登录时,用户写入引用路径 /auth/{authId}/connections 并同时设置 onDisconnect 以删除该值。

以下是在 rtdb 中设置状态的 Android 应用程序代码:

getFirebaseDatabase().goOnline();
DatabaseReference.goOnline();

// Since I can connect from multiple devices, we store each connection instance separately
// any time that connectionsRef's value is null (i.e. has no children) I am offline
final FirebaseDatabase database = getFirebaseDatabase();
final DatabaseReference myConnectionsRef = database.getReference("/auth/" + getFirebaseAuth().getUid() + "/connections");

// Stores the timestamp of my last disconnect (the last time I was seen online)
final DatabaseReference lastOnlineRef = database.getReference("/auth/" + getFirebaseAuth().getUid() + "/lastOnline");

connectedRef = database.getReference(".info/connected");
presenceChangeListener = connectedRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot snapshot) {
boolean connected = snapshot.getValue(Boolean.class);
if (connected) {
DatabaseReference con = myConnectionsRef.push();

// When this device disconnects, remove it
con.onDisconnect().removeValue()
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
// Add this device to my connections list
// this value could contain info about the device or a timestamp too
con.setValue("ANDROID");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "### Failed to set onDisconnect ###");
e.printStackTrace();
}
});

// When I disconnect, update the last time I was seen online
lastOnlineRef.onDisconnect().setValue(ServerValue.TIMESTAMP);
}
}

@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, "Listener was cancelled at .info/connected");
}
});

我遇到的问题是,如果用户注销,onDisconnect 不会执行,除非我首先手动断开与 rtdb 的连接。我假设在实时数据库上运行的代码被拒绝了,因为授权不再有效。

//If I don't go offline first the record in rtdb will not be removed.
DatabaseReference.goOffline();

AuthUI.getInstance().signOut(this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
public void onComplete(@NonNull Task<Void> task) {
// user is now signed out
Log.d(TAG, "Logged out");
application.clearData();
DatabaseReference.goOffline(); //This doesn't cause a presence update here
finish();
}
});

以上是我正在使用的解决方法,首先告诉数据库goOffline 然后注销。如果用户通过其他方式注销(网络应用程序正在查看是否有多个选项卡正在使用该应用程序并且有一个注销),用户将留下一个未删除的连接。

如果我在注销前不调用 goOffline(),即使我强行关闭应用程序,rtdb 中的连接也不会被删除。
我还验证了如果我将 rtdb 规则更改为 ".write": "true" <-这不好,我可以让一切正常工作。这告诉我,当用户注销身份验证时,运行 onDisconnect 的权限被拒绝。

我希望我的实时规则是这样的。

{
"rules": {
"auth": {
"$uid": {
".read": "auth != null && auth.uid == $uid",
".write": "auth != null && auth.uid == $uid"
}
}
}
}

我希望 onDisconnect 在设置 onDisconnect 时仍然能够在用户授权的情况下执行。

最佳答案

当您附加一个 onDisconnect() 处理程序时,您将在 Firebase 服务器上注册一个延迟写入。在附加处理程序时和触发处理程序时都会检查是否允许写入。并且由于您的用户在触发写入时已注销,因此它会被您的规则拒绝。没有更改此行为的配置选项,因此您必须想出一种不同的方法。

关于android - 注销后实时数据库onDisconnect不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57011583/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com