使用 Firebase for Android,我将以下数据结构用于具有有限数量插槽的聊天室:
/rooms
/<roomid, generated by push()>
/users
one: null
two: null
three: null
为了让我的客户使用其中一个插槽(one
to three
),我使用了此处提供的以下代码(JavaScript 版本):
var userid = "myuserid";
var ref = new Firebase("<my-firebase>.firebaseio.com/rooms/<roomid>/users");
ref.transaction(function(users) {
if (!users.one) {
// Claim slot 1
users.one = userid;
return users;
} else if (!users.two) {
// Claim slot 2
users.two = userid;
return users;
} else if (!users.three) {
// Claim slot 3
users.three = userid;
return users;
}
// Room is full, abort the transaction.
return;
}, function(err, committed, snapshot) {
if (committed && !err) {
// Joined room successfully.
} else {
// Could not join room because it was full.
}
});
经过一些测试,我发现这不起作用。我对以下两个解释它为什么不起作用的假设是正确的吗?
- 在
runTransaction(...)
(Android) 或transaction(...)
(JavaScript) 中,您必须将可选参数fireLocalEvents
(Android) 或applyLocally
(JavaScript) 设置为false
,否则您将收到来自事务的事件,尽管它可能不会成功。 - 即使
fireLocalEvents
(Android) 或applyLocally
(JavaScript) 设置为,该引用上false
的事件也会在您的事务成功返回之前触发。这是预期的行为吗?onChildChanged(...)
onComplete(...)
对于这种特殊情况,这意味着在我知道我自己是最后一个空位 (in ChildEventListener.onChildChanged(...)
)之前,我将收到关于聊天室已满 (in) 的通知。Transaction.Handler.onComplete(...)
假设,如果房间已满...
- 我在那里有一个插槽,执行了一些代码并启动了一些新的东西。
- 而且我没有得到任何插槽,我只想从列表中隐藏房间(因为它不再可用)。
如果我想这样做,我必须将完整的逻辑移到ChildEventListener.onChildChanged(...)
,因为那是我首先接收事件的地方,对吧?否则,在我知道我是那里的最后一个位置之前,房间就会被隐藏起来。
有任何想法吗?