我下面有一个节点文章,其中包含用户ID,在一个ID下,我有一个愿望清单名称,然后是这些文章和愿望清单信息,因此,当我想要更改愿望清单名称时,我要使用我想要的节点的子节点进行更改,然后用新名称和相同的子代创建一个新的w,然后删除旧的愿望清单。因此,我想创建一个事务以在一次连接不良的情况下同时完成所有工作或根本不执行所有事务,因为如果操作中断,我可以丢失数据。这是我当前的代码,以及如何将该操作放入Firebase事务中。谢谢您的帮助 !
func updateWishlist(wishlist:WishList,newName:String){
if((reachability.connection == .wifi) || (reachability.connection == .cellular)){
self.showProgressView()
let child = self.ref.child("Articles").child((user!.uid)!)
self.ref.child("Articles").child((user!.uid)!).child(wishlist.name) .updateChildValues(["name":newName]) { error, _ in
if(error == nil){
//create new node with new name
let oldName=wishlist.name
child.child(wishlist.name).observeSingleEvent(of: .value, with: { (snapshot) in self.ref.child("Articles").child((GlobalVar.user!.uid)!).child(newName).setValue(snapshot.value as! [String : Any]) { error, _ in
if(error == nil){
self.dismissHUD(isAnimated: true)
self.title=newName
self.showMessage("Wishlist modifier !", type: .success, options: [.position(.bottom)])
self.ref.child("Articles").child((GlobalVar.user!.uid)!).child(oldName).removeValue()
}
else{
self.dismissHUD(isAnimated: true)
print("update wishlist name transaction failed")
}
}
user?.wishLists[self.passedWishlistIndex!].name=newName
})
}
self.dismissHUD(isAnimated: true)
}
}
}
答案 0 :(得分:1)
这个问题实际上归结于此声明
我想更改愿望清单名称,将节点的孩子(带走) 要更改,然后我使用新名称创建一个新名称,并且相同 孩子们,然后我删除了旧的愿望清单
解决方法是不要将动态数据用作节点密钥。重组数据将消除交易的需要。
愿望清单名称应使用 .childByAutoId 创建的密钥存储为节点的子代。
为澄清起见,您的结构目前是 这个
Articles
article_0
dadoune //wish list name
solo //with list name
articles
xxx
yyy
zzz
artical_1
artical_2
这是行得通的;将愿望清单名称移至子节点。
Articles
article_0
-Jk0ksk0kj9sdfsdf //wish list key created with .childByAutoId
wish_list_name: "dadoune" //store the name as a child
-Jyl909m9mm3o99jt //wish list key created with .childByAutoId
wish_list_name: "solo" //store the name as a child
articles
xxx
yyy
zzz
article_1
article_2
通过将动态愿望清单名称存储为子代,您可以随时根据需要进行更改,而无需读取节点,删除节点,更改名称以及重新编写节点。