注销Firebase身份验证的用户后写入Firestore

时间:2020-05-13 19:34:54

标签: ios swift firebase google-cloud-firestore firebase-authentication

在我的应用中,我使用一种简单的注销方法。此方法删除当前的FCM令牌,清除设备上的文档文件夹,然后注销用户。我在SceneDelegate中的身份验证侦听器对注销做出反应,并将用户带回登录/注册视图控制器。我还希望我的应用更新Firestore中的某些文档(在这种情况下,我存储在用户文档中的FCM令牌阵列)

我遇到的问题是,当我将Auth.auth()。signOut()放入完成处理程序中时,该应用程序需要太多时间来做出响应,尤其是在Internet连接不良或没有连接的情况下。当我先注销用户时,Firestore写入失败,因为该用户不再通过身份验证。

我已经部分解决了云功能的问题,之后让它在Firestore中进行清理。但是我想使用设备代替。

我的问题是:

a)是否有一种方法可以同时验证和启动Firestore写入并注销用户,而不必等待写入完成?

b)是否有某种方法可以缓存此Firestore的写入内容,直到手机再次处于联机状态,即使该应用程序已在两次关闭之间也是如此?

func logoutUser() {

    InstanceID.instanceID().deleteID { error in
        if let error = error {
            os_log(.error, "%@", error.localizedDescription)
        }
    }
    do {
        try Auth.auth().signOut()

        localStorage_Methods.clearLocalFiles()

        self.deleteAllFcmTokens() {
        ///completion handler
        }

    } catch let signOutError as NSError {
        os_log(.error, "%@", signOutError)
    }
}




func deleteFcmToken(passedOnMethod: @escaping () -> () ) {

    guard let currentUserA = K.Globals.currentUser else { return }

    InstanceID.instanceID().instanceID { (result, error) in
        if let error = error {
            os_log(.error, "%@", error.localizedDescription)
        } else if let result = result {
            self.db.collection(K.FStore.collectionOf_RegisteredUsers_Name).document(currentUserA.uid)
                .updateData([
                    K.FStore.Users.fcmTokens: FieldValue.arrayRemove([result.token])
                ]) { (error) in
                    if let error = error {
                        os_log(.error, "%@", error.localizedDescription)
                    } else {
                        passedOnMethod()
                    }
            }
        }
    }
}

我的场景代表:

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?
    let fb_Auth_Methods = FB_Auth_Methods()

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        Auth.auth().addStateDidChangeListener { (auth, user) in

            if user != nil {
                self.setAndGoToRootView(withIdentifier: K.ViewItems.mainNavigationViewController)
                K.Globals.currentUser = user

            } else {
                self.setAndGoToRootView(withIdentifier: K.ViewItems.rootNavigationController)
                K.Globals.currentUser = nil
                self.fb_Auth_Methods.detachTrackLoginStatusListener()
            }
        }

        guard let _ = (scene as? UIWindowScene) else { return }
    }


func setAndGoToRootView(withIdentifier: String) {
        let storyboard = UIStoryboard(name: K.ViewItems.mainStoryboard, bundle: nil)
        var viewController: UIViewController = UIViewController()
        viewController = storyboard.instantiateViewController(withIdentifier: withIdentifier)
        self.window?.rootViewController = viewController
        self.window?.makeKeyAndVisible()

    }

1 个答案:

答案 0 :(得分:1)

是否有一种方法可以同时验证和启动Firestore写入并注销用户,而不必等待写入完成?*

不幸的是,没有。调用signOut()方法后,它将使您的身份验证令牌无效。如果写操作成功完成才能使令牌无效,那么它可能会成功。否则它将失败。

是否有办法以某种方式缓存此Firestore的写入内容,直到手机再次联机,即使应用程序之间已关闭也是如此?*

Firestore默认情况下支持离线持久性,这意味着您执行的所有写入(事务除外)都将被缓存,并在您连接到互联网后立即执行。

由于Firebase admin SDK会绕过安全规则,因此通常在后端进行清理通常是更好的做法,您将能够清理移动客户端无法访问的数据。