我正在寻找有关如何在从多个设备进行android的并发访问中锁定/解锁firebase的写访问的提示
我希望能够做这样的事情:
我的第一个想法是增加超时。如果您未在允许的数量之前解锁,则锁定写操作可能会单独失效,以确保没有设备可以阻止访问。
我阅读了有关交易的信息,但我认为它不适合我的需求。因为我在处理时需要访问多个路径。
在任何人都知道如何实现设备必须先获得才能进行写入的锁定/解锁写入访问权限?
感谢任何想法。
PS:我的可运行同步任务已经很好地完成了工作,我只是在寻找如何锁定和解锁Firebase的写访问权限,以确保在处理某些数据时没有其他设备可以破坏数据。
答案 0 :(得分:1)
实时数据库和Cloud Firestore都没有一种机制,您可以在处理数据库时在任意时间内强制锁定整个数据库,甚至只是其中一部分。这样的事情根本无法在现实世界中扩展。
这两个数据库都提供事务处理机制,这是原子地,一致地执行读写的唯一方法。如果您绝对需要其他形式的锁定,则云托管数据库可能不是您的最佳选择。要么,要么通过您控制的单个中间件来集中所有访问,但这种中间件也无法很好地扩展。
答案 1 :(得分:1)
因此,实际上,有一种方法。道格(Doug),在没有答案之前,也许您应该尝试打开思路,而不是直接寻求快速答案。
如何操作: -使用交易 -在所需的补丁程序中读取条目并锁定所需的补丁程序,条目为guid +设备的时间戳。 -如果时间戳<小于您的时间戳,则说明补丁未锁定,您可以通过编写GUID和时间戳+需要锁定的时间来获取补丁。 -当交易成功时,您就是赢家,可以做任何您想做的事情。 -完成后,写入当前时间戳以释放锁定
答案 2 :(得分:1)
如果有人需要它,这就是我如何在特定路径3s上获取并获得一个锁的方法。 -在每个表(路径)上,您可以将一个tableInfo关联起来,其中包含该路径的锁。 -如果没有其他人需要锁,则获取,释放并延长时间。您可以在尝试获取此锁的其他设备的GUID的另一个字段上添加侦听器。而且很高兴实现它,而不是延长您的时间。
fbBase.child(tableInfoChildRef).child(TableInfo.Field.Lock.name).runTransaction(new Transaction.Handler() {
public Map<String, Object> lock(){
Map<String, Object> data = new ArrayMap<>();
data.put(TableInfo.Field.Lock.guid, AppGUID.get().toString());
data.put(TableInfo.Field.Lock.timestamp, System.currentTimeMillis()+3000);
return data;
}
@NonNull
@Override
public Transaction.Result doTransaction(@NonNull MutableData mutableData) {
if(mutableData.getValue() == null) {
mutableData.setValue(lock());
return Transaction.success(mutableData);
}else{
Long lockTimestamp = mutableData.child(TableInfo.Field.Lock.timestamp).getValue(Long.class);
if(lockTimestamp < System.currentTimeMillis()){
mutableData.setValue(lock());
return Transaction.success(mutableData);
}
}
return Transaction.abort();
}
@Override
public void onComplete(@Nullable DatabaseError databaseError, boolean b, @Nullable DataSnapshot dataSnapshot) {
if(b) LogDelay.send("WIN");
else LogDelay.send("LOSE");
}
});