Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Firebase数据库-限制每个用户仅更新一次值_Android_Firebase Realtime Database_Firebase Security - Fatal编程技术网

Android Firebase数据库-限制每个用户仅更新一次值

Android Firebase数据库-限制每个用户仅更新一次值,android,firebase-realtime-database,firebase-security,Android,Firebase Realtime Database,Firebase Security,我在android应用程序中使用Firebase实时数据库, 该应用程序包含文章,我想通过所有应用程序用户向文章添加视图数 数据库包含一个子项(ViewScont)及其值(是一个数字) 我需要在新用户每次查看文章时更新该值(增加1)(概念类似于YouTube视频视图) 用户必须通过匿名身份验证才能更新该值,但不能多次进行验证 我将逻辑集成到应用程序中来实现这一点,效果非常好。 但我担心的是,如果有人试图连接到我的应用程序之外的数据库(使用他们自己的代码),并不断增加值 我目前的安全规则是: "V

我在android应用程序中使用Firebase实时数据库, 该应用程序包含文章,我想通过所有应用程序用户向文章添加视图数

数据库包含一个子项(ViewScont)及其值(是一个数字) 我需要在新用户每次查看文章时更新该值(增加1)(概念类似于YouTube视频视图)

用户必须通过匿名身份验证才能更新该值,但不能多次进行验证

我将逻辑集成到应用程序中来实现这一点,效果非常好。 但我担心的是,如果有人试图连接到我的应用程序之外的数据库(使用他们自己的代码),并不断增加值

我目前的安全规则是:

"ViewsCount"
{
  ".write": "newData.exists() && auth!==null",
  ".validate" "newData.val()===data.val()+1"
}
"users": { 
  "$user_id": { 
    ".write": "auth.uid===$user_id", 
    ".read": "auth.uid===$user_id ",
  }
}
是否有办法通过安全规则将该值的更新限制为每个用户仅更新一次?。 错误:

更新:
当然有,但你得做些额外的工作。第一件事是在数据库中跟踪已经看过每篇文章的人。例如,保存他们的UID列表,如下所示:

viewedBy: {
  uidOfKarim: true,
  uidOfPuf: true
}
现在,当有人查看一篇文章时,他们会将UID写入
viewedBy
,同时增加该文章的查看次数。在代码中,可以简单到:

DatabaseReference countRef = FirebaseDatabase.getInstance().getReference("ViewsCount");
countRef.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot dataSnapshot) {
    String uid = FirebaseAuthentication.getCurrentUser().getUid();
    Long newCount = dataSnapshot.getValue(Long.class) + 1;
    Map<String, Object> updates = new HashMap<String, Object>();
    updates.put("viewedBy/"+uid, true);
    updates.put("ViewsCount", newCount);
  }

  @Override
  public void onCancelled(DatabaseError databaseError) {
    throw databaseError.toException();
  }
}
语法有点长,因为它同时检查
ViewScont
ViewedBy
数据。只有当写入增量为1且来自尚未计数的用户时,写入才会成功。如果它们之前已经计数过,或者没有增加1,则写入将被拒绝

这里有一种边缘情况:如果多个用户几乎同时查看,他们的一次写入可能会被拒绝,因为他们实际上没有增加值:

user1       user2                   database
  |           |                        |
read_count ------------------->        |
  |           |                        |
  |        read_count -------->        |
  |           |                        |
  |        <------------------- 2      |
  |           |                        |
  |           |   <------------ 2      |
  |           |                        |
set_count 3 ------------------->       |
  |           |                        |
  |        set_count -------->         |
  |           |                        |
  |        <------------------- ok     |
  |           |                        |
  |           |   <------------ ACCESS |
  |           |                 DENIED |
  |           |                        |

这是在任何其他人有相同问题时起作用的安全规则:

{"rules": {
"views": { 
  ".write": "auth != null",
".validate": "newData.hasChildren(['ViewsCount', 'viewedBy'])",

"ViewsCount": {
".read": "auth != null",
".validate":"data.parent().child('viewedBy').child(auth.uid).exists()== false"
},

"viewedBy": { 
"$user_id": { 
".validate": " auth.uid===$user_id && !data.exists() && newData.exists() &&
  newData.parent().parent().child('ViewsCount').val() === 
data.parent().parent().child('ViewsCount').val()+1
&& newData.val()===true"}},

     },

谢谢,但这里的问题和我所担心的是,如果其他人出于恶意编写了一个不同的代码,他在不将UID添加到节点“viewdBy”的情况下,将ViewScont值的增量增加到他想要的次数。他只需要反编译应用程序,提取json文件,然后用相同的包名编写自己的代码。我想我要问的是,在ViewScont增加后,是否可以强制将查看器UID添加到viewdBy节点。由于只有我可以访问和更改这些安全规则,因此,如果不将UID写入查看的,则无法进行增量操作,每个用户只能根据相同的规则执行一次。请尝试一下,如果它不起作用,请告诉我。我会感谢您。“.value”:返回一个错误(错误保存规则-第23行:应为“{”)。您的意思是“.validate”?
"52469568": {
  "ViewsCount": 10,
}
{"rules": {
"views": { 
  ".write": "auth != null",
".validate": "newData.hasChildren(['ViewsCount', 'viewedBy'])",

"ViewsCount": {
".read": "auth != null",
".validate":"data.parent().child('viewedBy').child(auth.uid).exists()== false"
},

"viewedBy": { 
"$user_id": { 
".validate": " auth.uid===$user_id && !data.exists() && newData.exists() &&
  newData.parent().parent().child('ViewsCount').val() === 
data.parent().parent().child('ViewsCount').val()+1
&& newData.val()===true"}},

     },