【问题标题】:Firebase offline functions on iOSiOS 上的 Firebase 离线功能
【发布时间】:2017-06-10 11:47:11
【问题描述】:

我使用 Firebase 离线功能,特别是我使用它来确定用户上次在线或在线的时间。在测试过程中,我遇到了这样一个问题,如果我注销,断开功能不起作用,虽然我没有取消断开功能。我明白在注销之前,我可以自己发送这个数据,但是这个功能的意义会从盒子里消失。告诉我如何解决这个问题?

这个函数决定了用户的活动,我在MainTabBarController中调用它(它被用作根控制器)

func setupLastSeenActivity() {
        DispatchQueue.main.async {
            let realmManager = RealmManager()
            guard let currentUserID = realmManager.getCurrentUser()?.id else { return }
            DispatchQueue.global(qos: .background).async {
                let ref = Database.database().reference().child(MainGateways.users.rawValue).child(currentUserID)
                let userSearchLocationRef = Database.database().reference().child(UserSearchLocationKeys.userSearchLocationModel.rawValue).child(currentUserID)

                let parameters = [UserSubgateways.isOnline.rawValue : true]
                ref.updateChildValues(parameters, withCompletionBlock: { (error, ref) in

                })

                userSearchLocationRef.updateChildValues(parameters, withCompletionBlock: { (error, ref) in

                })

                let disconnectParameters = [UserSubgateways.isOnline.rawValue : false, UserSubgateways.lastSeenTimeStamp.rawValue : ServerValue.timestamp()] as [String : Any]

                ref.onDisconnectUpdateChildValues(disconnectParameters, withCompletionBlock: { (error, ref) in
                    guard let _error = error else { return }
                    debugPrint(_error.localizedDescription)
                })

                userSearchLocationRef.onDisconnectUpdateChildValues(disconnectParameters, withCompletionBlock: { (error, ref) in
                    guard let _error = error else { return }
                    debugPrint(_error.localizedDescription)
                })
            }
        }
    }

来自FirebaseAuthManager的注销功能

  func logOut(completion: (() -> Void)?) {
        DispatchQueue.main.async {
            do {
                let pushNotificationManager = PushNotificationManager()
                pushNotificationManager.unregisterPushNotification()
                pushNotificationManager.removeTokenWhenLogOut(success: nil)
                // Observers
                FIRFriendsDatabaseManager.shared.observeNewFriend(false, success: nil, fail: nil)
                FIRFriendsDatabaseManager.shared.observeFriendRemoved(false, success: nil, fail: nil)
                let firChatCardManager = FIRChatCardManager()
                firChatCardManager.syncChatCardModels(false)

                FacebookManager.logOut()
                Database.database().reference().removeAllObservers()

                let firebaseGeneralDatabaseManager = FirebaseDatabaseGeneralManager()
                firebaseGeneralDatabaseManager.logOut()
                try Auth.auth().signOut()
                let realmManager = RealmManager()
                realmManager.logOut()
                let appManager = AppManager()
                appManager.logOut(isDeleteAccount: false, completion: completion)
            } catch {
                debugPrint(error.localizedDescription)
            }
        }
    }

【问题讨论】:

  • 用户无需登录即可连接。用户无需连接即可登录。两者都是正常和预期的行为。您尝试使用 onDisconnect 处理程序实现的具体用例是什么?
  • @FrankvanPuffelen 我试图实现正确反映用户状态的可能性,即在线/离线。但我也认为 onDisconnect 处理程序对此并不理想,因为用户可以从多个设备登录他的帐户,例如只有一个设备会失去 Internet 连接。告诉我,Firebase 会考虑每个用户的连接数,如果是的话,在哪里可以找到有关如何使用它的信息。
  • presence sample in the documentation 跟踪每个用户的多个连接,正是出于这个原因。
  • @FrankvanPuffelen 好的,谢谢

标签: ios swift firebase firebase-realtime-database firebase-authentication


【解决方案1】:

我做了一个统计连接设备数量的云功能,如果连接设备数量为0,那么我设置值isOnline = false 并设置lastSeenTimeStamp

const functions = require('firebase-functions');
const admin = require('firebase-admin');

module.exports = functions.database.ref('userOnlineDevices/{userID}/{onlineSystemModelID}')
    .onWrite(event => {

        const snapshot = event.data;
        const userID = event.params.userID;
        const onlineSystemModelID = event.params.onlineSystemModelID;

        const currentData = event.data.current;
        const previousData = event.data.previous;

        console.log("currentData.val()", currentData.val(), "previousData.val()", previousData.val());

        if (currentData.val() && !previousData.val()) {
            // value created

            const checkUserRef = admin.database().ref("users").child(userID);
            const checkUserRefPromise = checkUserRef.once("value", function(checkUserRefSnap, error) {
                if (error) {
                    return console.log("created checkUserRefPromise error", error);
                }
                if (checkUserRefSnap.val()) {
                    const checkUserID = checkUserRefSnap.val()["id"];
                    if (checkUserID == null) {
                        return console.log("checkUserID == null")
                    } else {
                        console.log("checkUserID", checkUserID)
                    }

                    const recentActivityTimeStamp = Math.floor(Date.now() / 1000);
                    const userRef = admin.database().ref("users").child(userID);
                    const userRefPromise = userRef.update({
                        "isOnline": true
                    });

                    const userSearchLocationModelRef = admin.database().ref("userSearchLocationModel").child(userID);
                    const userSearchLocationModelRefPromise = userSearchLocationModelRef.update({
                        "isOnline": true,
                        "recentActivityTimeStamp": recentActivityTimeStamp
                    });

                    return Promise.all([userRefPromise, userSearchLocationModelRefPromise]);
                } else {
                    return console.log("checkUserRefSnap.val() == null")
                }
            });

            return Promise.all([checkUserRefPromise]);
        } else if (!currentData.val() && previousData.val()) {
            // value removed
            const checkUserRef = admin.database().ref("users").child(userID);
            const checkUserRefPromise = checkUserRef.once("value", function(checkUserRefSnap, error) {
                if (error) {
                    return console.log(error);
                }

                if (checkUserRefSnap.val()) {
                    const checkUserID = checkUserRefSnap.val()["id"];
                    if (checkUserID == null) {
                        return console.log("checkUserID == null")
                    } else {
                        console.log("checkUserID", checkUserID)
                    }

                    if (userID) {
                        const removedTimeStamp = new Date() / 1000;
                        const userRef = admin.database().ref("users").child(userID);
                        const userRefPromise = userRef.update({
                            "isOnline": false,
                            "lastSeenTimeStamp": removedTimeStamp
                        });

                        const userSearchLocationModelRef = admin.database().ref("userSearchLocationModel").child(userID);
                        const userSearchLocationModelRefPromise = userSearchLocationModelRef.update({
                            "isOnline": false,
                            "lastSeenTimeStamp": removedTimeStamp
                        });

                        return Promise.all([userRefPromise, userSearchLocationModelRefPromise]);
                    } else {
                        return console.log("removed, userID == null");
                    }
                } else {
                    return console.log("removed, checkUserRefSnap.val() == null");
                }
            });

           return Promise.all([checkUserRefPromise]);
        } else {
            // updated
            const checkUserRef = admin.database().ref("users").child(userID);
            const checkUserRefPromise = checkUserRef.once("value", function(checkUserRefSnap, error) {
                if (error) {
                    return console.log(error);
                }

                if (checkUserRefSnap.val()) {
                    const checkUserID = checkUserRefSnap.val()["id"];
                    if (checkUserID == null) {
                        return console.log("checkUserID == null")
                    } else {
                        console.log("checkUserID", checkUserID)
                    }

                    const recentActivityTimeStamp = Math.floor(Date.now() / 1000);
                    const userRef = admin.database().ref("users").child(userID);
                    const userRefPromise = userRef.update({
                        "isOnline": true
                    });

                    const userSearchLocationModelRef = admin.database().ref("userSearchLocationModel").child(userID);
                    const userSearchLocationModelRefPromise = userSearchLocationModelRef.update({
                        "isOnline": true,
                        "recentActivityTimeStamp": recentActivityTimeStamp
                    });

                    return Promise.all([userRefPromise, userSearchLocationModelRefPromise]);
                } else {
                    return console.log("updated checkUserRefSnap.val() == null");
                }
            });

            return Promise.all([checkUserRefPromise]);
        }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-01
    • 2021-11-25
    • 2016-04-01
    • 1970-01-01
    相关资源
    最近更新 更多