gpt4 book ai didi

java - 了解 Firebase 中的事务

转载 作者:行者123 更新时间:2023-12-01 21:57:11 25 4
gpt4 key购买 nike

我正在构建一个小型应用程序,用于在 Android Studio 中管理用户和类次。

我的数据库结构如下:

{
"config" : {
"20191108" : { // each date has a different amount of shifts under it
"-Lt53nxPc9_lBy7EvRQa" : { // generated key for shift
"endTime" : "00:00",
"name" : "morning",
"numOfEmps" : 2,
"startTime" : "00:00",
"users" : {
"12345" : true,
"54321" : true
},
"wage" : 0
}
}
},
"users" : {
"12345" : {
id: "12345",
password : "aaaaa"
},
"33333" : {
id: "33333",
password : "bbbbb"
},
"54321" : {
id: "54321",
password : "c3c3c3"
}
}
}

目标是允许用户将自己添加到他们选择的类次(根据限制)。

每个类次都有一个不同的 numOfEmps 字段,该字段指示可以将多少用户分配给该特定类次。

我在应用中定义了两个模型 - UserShift

我决定使用事务,因为我的应用程序将为多个用户提供服务,并且许多用户可能决定将自己分配到同一类次。

我的主要限制是,用户不得将自己多次分配到同一类次,并且在任何给定时刻不得将超过 numOfEmps 个用户分配到一个类次。

我的代码:

 add.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//Constraint No. 0
//chosen date < today's date, user cannot assign themselves to prior shifts
String today = DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.now());
if(today.compareTo(dates[0]) >= 0){
Toast.makeText(context, "Cannot assign to prior shifts", Toast.LENGTH_SHORT).show();
return;
}

DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("config").child(dates[0]).child(shift.getKey()).child("users").runTransaction(new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData mutableData) {

if(mutableData == null){
// Set value and report transaction success
mutableData.child(user.getId()).setValue(true);

return Transaction.success(mutableData);
}
// here I'd like to check if the user is already assigned
// or if numOfEmps is equal to number of children under "users" node
// and if so, abort transaction
return Transaction.success(mutableData);
}

@Override
public void onComplete(DatabaseError databaseError, boolean b,
DataSnapshot dataSnapshot) {
if(b){
// update Expandable List View
List<User> usersList = collection.get(shift);
usersList.add(user);
notifyDataSetChanged();
}else{
Toast.makeText(context, "User already assigned to shift", Toast.LENGTH_SHORT).show();
}
}
});
}
});

Firebase 的文档在单个对象(整数)上执行事务。

我希望扩展它来处理对象(用户)列表。

非常感谢您帮助解决此问题。谢谢。

最佳答案

现在您正在此处设置整个可变数据:

mutableData.setValue(user);

因此,您将使用 user 的值覆盖 /users 下的所有内容。

您只想为特定用户设置数据,您可以这样做:

mutableData.child(user.getKey()).setValue(user);
<小时/>

关于您的方法的一些附加说明:

  • 由于您没有在任何地方使用 shiftRef.addListenerForSingleValueEvent() 的 DataSnapshot,因此我建议删除该监听器。一般来说:将事务放入常规监听器中是一种严重的代码味道,因为您的交易应该只依赖于您在交易本身中读取的数据(否则:为什么要使用交易开始)。
  • 如果您想在交易内创建推送 ID,只需调用 shiftRef.push().getKey() 即可。这是纯粹的客户端操作。
  • 当您向列表中添加更多用户时,在列表上运行事务通常会导致性能问题/争用。考虑使用不存在此问题的数据模型。
  • 例如:您最好将用户存储在他们的 ID 下。这样您就可以直接查找用户,而不必读取所有用户并搜索客户端(如果您有很多用户,则不会扩展)。因此,在这种情况下,您的事务可以在 /users/$uid 上运行。

关于java - 了解 Firebase 中的事务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58735153/

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