0

在我的iOS应用程序中,我想尝试在用户注销之前保存一段用户数据。Firebase:在登出前保存数据

- 具有相同问题的更新代码。在“填充完成块”之前打印“用户已登录”。

let tryToLogout = { 
    try! FIRAuth.auth()!.signOut() 
    print("USER HAS BEEN LOGGED OUT") 
} 

rootRef.child(path).setValue(value, withCompletionBlock: { (_,_) in 
    print("FELL INTO COMPLETION BLOCK") 
    tryToLogout() 
}) 

不幸的是,我有时会收到上的setValue企图否认权限。我认为这里发生的事情是用户通过在setValue占据之前退出而取消授权。如果不是因为signOut()调用明显位于setValue的完成块内部,这对我来说完全有意义。

任何解释?

UPDATED --------------------------------------------- --------------------------- 我有点想出了这个问题。 rootRef.child.setValue是我为了在整个项目中易于使用而创建的一个常规设置值函数。当我使用该函数的内容(上面看到的setValue代码)并单独运行它(不在单独的函数调用中)时,问题消失并且打印语句按正确顺序排列。我相信这意味着我的问题是由调用堆栈造成的。注销用户是调用堆栈中的最后一件事,因此它是调用堆栈中的第一件事情 - 首先执行。

下面的代码应该证明这个问题

func setFireBaseValue(path: String, value: NSObject, completionCode:()) { 
    getRootRef().child(path).setValue(value, withCompletionBlock: { (_,_) in 
     print("FELL INTO A COMPLETION BLOCK") 
     completionCode 
    }) 
} 

let tryToLogout = { 
    try! FIRAuth.auth()!.signOut() 
    print("USER HAS BEEN LOGGED OUT") 
} 

setFireBaseValue(path: "test", value: "hi" as NSString, completionCode: tryToLogout()) 
+0

建成块才会被调用一次'的setValue()'已经在服务器上执行,客户端已经接收的确认。我认为没有办法可以触发拒绝许可。如果您[启用调试日志记录](https://firebase.google.com/docs/reference/ios/firebasedatabase/interface_f_i_r_database.html#add018db6d76362436734f66daa471256),则可能会看到到底发生了什么。 –

+0

我添加了一个print(“FELL INTO COMPLETION BLOCK”)作为完成块内的第一行。然后我删除了signOut()并将其封装在包含打印的封闭内(“USER IS SIGNED OUT”)。然后我在完成块内部调用闭包。当所有这些都被执行时,“用户已签出”打印在“完成填充块”之前。它必须是在完成块之前调用signOut()方法,是的? – user3915477

+0

这证明'tryToLogout'在调用完成块之前被调用。它必须从其他地方调用。在调用tryToLogout'时查看调用堆栈的任何方法来查看它来自哪里? –

回答

0

您可以使用OnCompleteListener监听成功添加数据的火力点数据库,并成功的数据更新用后注销。如果在保存数据时出现任何错误,请通知用户,并据此进行处理。

0

尝试使用: -

rootRef.child(path).setValue(value, withCompletionBlock: { (err,ref) in 

if err == nil && ref == nil{ 
    try! FIRAuth.auth()!.signOut() 
    } 
})