Java 在Firebase数据库中编写规则
我正在android上构建一个应用程序,用于管理用户和轮班。每个用户可以被分配到多个班次,并且每个班次可以有多个用户。每个班次都与一个日期相关联 以下是我的数据库在firebase中的结构:Java 在Firebase数据库中编写规则,java,android,firebase,firebase-realtime-database,firebase-security,Java,Android,Firebase,Firebase Realtime Database,Firebase Security,我正在android上构建一个应用程序,用于管理用户和轮班。每个用户可以被分配到多个班次,并且每个班次可以有多个用户。每个班次都与一个日期相关联 以下是我的数据库在firebase中的结构: { "shift-assign" : { "key1" : { "111" : true, "222" : true, "888" : true }, "key2" : { "111" : true, "222" :
{
"shift-assign" : {
"key1" : {
"111" : true,
"222" : true,
"888" : true
},
"key2" : {
"111" : true,
"222" : true
}
},
"shifts" : {
"key1" : {
"date" : "20191202",
"endTime" : "02:00",
"numOfEmps" : 4,
"startTime" : "21:00",
"wage" : 30
},
"key2" : {
"date" : "20191202",
"endTime" : "12:00",
"numOfEmps" : 3,
"startTime" : "08:00",
"wage" : 10
},
"key3" : {
"date" : "20191203",
"endTime" : "06:00",
"numOfEmps" : 3,
"startTime" : "00:00",
"wage" : 30
}
},
"user-assign" : {
"111" : {
"key1" : true,
"key2" : true
},
"222" : {
"key1" : true,
"key2" : true
},
"888" : {
"key1" : true
}
},
"users" : {
"111" : {
"active" : true,
"email" : "111",
"firstName" : "aaa",
"id" : "111",
"lastName" : "aaa",
"password" : "111",
"phone" : "1111111"
},
"222" : {
"active" : true,
"email" : "222",
"firstName" : "bbb",
"id" : "222",
"lastName" : "bbb",
"password" : "222",
"phone" : "4444444"
},
"888" : {
"active" : false,
"email" : "888",
"firstName" : "ccc",
"id" : "888",
"lastName" : "ccc",
"password" : "888",
"phone" : "5555555"
},
"99999" : {
"active" : true,
"firstName" : "Admin",
"id" : "99999",
"password" : "123"
}
}
}
当用户尝试将自己分配到一个班次时,我想在实际将其分配到班次之前检查一些约束
我尝试使用一个事务,但代码出错了,因为我需要引用事务中的不同节点
我的代码现在如下所示:
private void AssignUserToShift() {
// Constraint No. 0
// user cannot be assigned to shifts whose date < today
if(dates[0].compareTo(LocalDateTime.now().toLocalDate().format(dtf)) < 0){
Toast.makeText(getApplicationContext(), "Cannot assign to prior dates", Toast.LENGTH_SHORT).show();
return;
}
Map<String, Object> pathsToUpdate = new HashMap<>();
pathsToUpdate.put("shift-assign/" + shiftKey + "/" + userId, true);
pathsToUpdate.put("user-assign/" + userId + "/" + shiftKey, true);
mDatabase.updateChildren(pathsToUpdate, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
if(databaseError == null) {
// add to adapter's list in GUI
AddUserToList();
}else{
Toast.makeText(getApplicationContext(), "Could not update database entries", Toast.LENGTH_SHORT).show();
}
}
});
}
private void AssignUserToShift(){
//第0号限制
//无法将用户分配到日期<今天的班次
如果(日期[0]。比较到(LocalDateTime.now().toLocalDate().format(dtf))<0){
Toast.makeText(getApplicationContext(),“无法分配到以前的日期”,Toast.LENGTH_SHORT.show();
返回;
}
Map pathsToUpdate=new HashMap();
pathsToUpdate.put(“移位赋值/”+shiftKey+“/”+userId,true);
pathsToUpdate.put(“用户分配/”+userId+“/”+shiftKey,true);
mDatabase.updateChildren(路径更新,新数据库引用.CompletionListener(){
@凌驾
公共void onComplete(@Nullable-DatabaseError-DatabaseError,@NonNull-DatabaseReference-DatabaseReference){
if(databaseError==null){
//添加到GUI中适配器的列表
AddUserToList();
}否则{
Toast.makeText(getApplicationContext(),“无法更新数据库条目”,Toast.LENGTH_SHORT.show();
}
}
});
}
相反的方法是:
private void RemoveUserFromShift() {
mUser user = userList.stream()
.filter(u -> u.getId().equals(userId))
.findAny()
.orElse(null);
if(user == null){
Toast.makeText(UsersAssignedActivity.this, "You are not assigned to this shift.", Toast.LENGTH_SHORT).show();
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(UsersAssignedActivity.this, R.style.AlertDialogCustom);
builder.setMessage("Do you wish to remove yourself from this shift?");
builder.setCancelable(false);
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
Map<String, Object> pathsToDelete = new HashMap<>();
pathsToDelete.put("shift-assign/" + shiftKey + "/" + userId, null);
pathsToDelete.put("user-assign/" + userId + "/" + shiftKey, null);
mDatabase.updateChildren(pathsToDelete, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(@Nullable DatabaseError databaseError, @NonNull DatabaseReference databaseReference) {
if(databaseError == null){
// remove from adapter's list in GUI
RemoveUserFromList();
}else{
Toast.makeText(UsersAssignedActivity.this, "Could not delete database entries", Toast.LENGTH_SHORT).show();
}
}
});
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int i) {
dialog.cancel();
}
});
AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void RemoveUserFromShift(){
mUser user=userList.stream()
.filter(u->u.getId().equals(userId))
.findAny()
.orElse(空);
if(user==null){
Toast.makeText(UsersAssignedActivity.this,“您没有被分配到这个班次。”,Toast.LENGTH_SHORT.show();
返回;
}
AlertDialog.Builder=新建AlertDialog.Builder(UsersAssignedActivity.this,R.style.AlertDialogCustom);
setMessage(“您希望从该班次中退出吗?”);
builder.setCancelable(false);
builder.setPositiveButton(“是”,
新建DialogInterface.OnClickListener(){
公共void onClick(对话框接口对话框,int i){
Map pathsToDelete=new HashMap();
pathsToDelete.put(“移位赋值/”+shiftKey+“/”+userId,null);
pathsToDelete.put(“用户分配/”+userId+“/”+shiftKey,null);
mDatabase.updateChildren(路径stodelete,新数据库引用.CompletionListener(){
@凌驾
公共void onComplete(@Nullable-DatabaseError-DatabaseError,@NonNull-DatabaseReference-DatabaseReference){
if(databaseError==null){
//从GUI中的适配器列表中删除
RemoveUserFromList();
}否则{
Toast.makeText(UsersAssignedActivity.this,“无法删除数据库条目”,Toast.LENGTH_SHORT.show();
}
}
});
}
});
builder.setNegativeButton(“否”,
新建DialogInterface.OnClickListener(){
公共void onClick(对话框接口对话框,int i){
dialog.cancel();
}
});
AlertDialog AlertDialog=builder.create();
alertDialog.show();
}
所以我想我应该使用规则来代替,并检查服务器端的约束
我想编写满足以下条件的规则-
numOfEmps
等于shift-assign/shiftKey
下的子节点数)我怎么写这些规则 您的问题有一个非常广泛的用例。我将向您展示如何从第一个要求开始: 用户不能分配到已满的班次。(其numOfEmps等于shift assign/shiftKey下的子节点数) 安全规则无法对数据执行任何聚合。由于此要求需要比较两个值,因此这两个值必须存储在数据库中规则中已知的路径上 您已经有了
numOfEmps
,但是您还需要存储已经注册轮班的人数。例如,您可以将注册人数添加到班次中,然后在每次添加/删除时进行更新:
"shifts" : {
"key1" : {
"date" : "20191202",
"endTime" : "02:00",
"numOfEmps" : 4,
"numSignups" : 3,
"startTime" : "21:00",
"wage" : 30
},
现在,您可以在安全规则中检查是否存在以下打开的插槽:
{
"rules": {
"shift-assigns": {
"$shiftid": {
"$uid": {
".validate": "root.child('/shifts/$shiftid/numSignups').val() < root.child('/shifts/$shiftid/numOfEmps').val()"
}
}
}
}
}
{
“规则”:{
“班次分配”:{
“$shiftid”:{
“$uid”:{
.validate:“root.child('/shifts/$shiftid/numSignups').val()
当然,您还需要确保用户:
- 只能使用som在班次中添加/删除自己