Firebase实时数据库在这种情况下并发请求会发生什么情况?

t1qtbnec  于 2023-01-27  发布在  其他
关注(0)|答案(2)|浏览(142)

我的数据库中有两个节点itemsmy_items
我有一个执行multi-path update的函数,这个函数从items中删除一个项目,并将其添加到用户的my_items中:
我保护my_items节点的方式是,只有当items中存在该项目时,您才可以写入它,否则它将失败:

private void getItem(String uid, String item_key) {    
  Map<String, Object> updates = new HashMap<>();

  //delete item
  updates.put("items/" + item_key, null);

  //give the item to the user
  updates.put("my_items/" + uid + "/" + item_key, itemObject);

  mDatabaseReference.updateChildren(updates);
}

问题(理论上):

  • 知道Firebase Database逐个处理请求。

如果用户A、B、C、D同时为同一个item id调用getItem(..)函数:

    • 这是否合理:**

1.假设A的请求首先到达服务器,Succeeds
(now该项目已从items中删除,并添加到位于my_items的用户A)

  1. B:x1米12英寸1x
    (因为items中不再存在该项目,所以my_items的安全规则阻止此操作)
  2. C:x1米15英寸1x
    (same原因)
    1.直径:x1米16英寸1x
    (same原因)
    "* 这是真的吗,还是我弄错了**
    谢谢。
piv4azn7

piv4azn71#

Firebase实时数据库按顺序处理(写入)操作。因此,在处理下一个操作之前,任何先前的写入操作都将完成。这意味着先前用户写入的任何数据都将出现在安全规则评估中的root变量中,以供后续写入操作使用。

iklwldmw

iklwldmw2#

本文讨论原子操作。RTDB在请求到达时执行操作。RTDB在事件到达时处理事件。还有一个问题可能与Does Firebase always guarantee added events in order?相关
您可以...在对两个位置进行单个原子更新时执行此操作:
JavaScript语言

var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
// Generate a new push ID for the new post
var newPostRef = ref.child("posts").push();
var newPostKey = newPostRef.key();
// Create the data we want to update
var updatedUserData = {};
updatedUserData["user/posts/" + newPostKey] = true;
updatedUserData["posts/" + newPostKey] = {
  title: "New Post",
  content: "Here is my new post!"
};
// Do a deep-path update
ref.update(updatedUserData, function(error) {
  if (error) {
    console.log("Error updating data:", error);
  }
});

java

Firebase ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
// Generate a new push ID for the new post
Firebase newPostRef = ref.child("posts").push();
String newPostKey = newPostRef.getKey();
// Create the data we want to update
Map newPost = new HashMap();
newPost.put("title", "New Post");
newPost.put("content", "Here is my new post!");
Map updatedUserData = new HashMap();
updatedUserData.put("users/posts/" + newPostKey, true);
updatedUserData.put("posts/" + newPostKey, newPost);
// Do a deep-path update
ref.updateChildren(updatedUserData, new Firebase.CompletionListener() {
   @Override
   public void onComplete(FirebaseError firebaseError, Firebase firebase) {
       if (firebaseError != null) {
           System.out.println("Error updating data: " + firebaseError.getMessage());
       }
   }
});

目标-C

Firebase *ref = [[Firebase alloc] initWithUrl: @"https://<YOUR-FIREBASE-APP>.firebaseio.com"];
// Generate a new push ID for the new post
Firebase *newPostRef = [[ref childByAppendingPath:@"posts"] childByAutoId];
NSString *newPostKey = newPostRef.key;
NSString *updateUserPath = [NSString stringWithFormat:@"users/posts/%@", newPostKey];
NSString *updatePostPath = [NSString stringWithFormat:@"posts/%@", newPostKey];
// Create the data we want to update
NSMutableDictionary *updatedUserData = [[NSMutableDictionary alloc] init];
[updatedUserData setValue:[NSNumber numberWithBool:YES] forKey:updateUserPath];
[updatedUserData setValue:@{@"title": @"New Post", @"content": @"Here is my new post!"} forKey:updatePostPath];
// Do a deep-path update
[ref updateChildValues:updatedUserData withCompletionBlock:^(NSError *error, Firebase *ref) {
    if (error) {
        NSLog(@"Error updating data: %@", error.debugDescription);
    }
}];

雨燕

"https://<YOUR-FIREBASE-APP>.firebaseio.com") // Generate a new push
ID for the new post let newPostRef =
ref.childByAppendingPath("posts").childByAutoId() let newPostKey =
newPostRef.key // Create the data we want to update let
updatedUserData = ["users/posts/(newPostKey)": true,
"posts/(newPostKey)": > ["title": "New Post", "content": "Here is my
new post!"]] // Do a deep-path update
ref.updateChildValues(updatedUserData, withCompletionBlock: { (error,
ref) -> > Void in
    if (error) {
        print("Error updating data: (error.description)")
    } })

深度路径更新使您可以编写更干净的代码,并轻松地对Firebase数据库中多个节点的数据进行非规范化处理。

相关问题