1

Ich benutze Firebase Offline-Funktionen, insbesondere verwende ich es um festzustellen, wann der Benutzer zuletzt online war oder er online ist. Während des Testens bin ich auf ein Problem gestoßen, dass die Funktion Trennen funktioniert, wenn ich mich abmelde, obwohl ich die Funktionen Trennen nicht abbringe. Ich verstehe, dass ich vor dem Abmelden diese Daten selbst senden kann, aber dann wird die Bedeutung dieser Funktion aus der Box verschwinden. Sag mir, wie kann ich das beheben?Firebase Offline-Funktionen auf iOS

Diese Funktion bestimmt, die Aktivität des Benutzers und Ich nenne es in MainTabBarController (es als Root-Controller verwendet wird)

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) 
       }) 
      } 
     } 
    } 

A Abmeldefunktion von 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) 
      } 
     } 
    } 
+0

Ein Benutzer kann ohne Anmeldung angemeldet werden. Ein Benutzer kann angemeldet werden, ohne dass eine Verbindung besteht. Beides ist normales und erwartetes Verhalten. Was ist der spezifische Anwendungsfall, den Sie mit dem onDisconnect-Handler implementieren möchten? –

+0

@FrankvanPuffelen Ich versuche, die Möglichkeit zu erkennen, den Status des Benutzers, nämlich online/offline zu reflektieren. Aber ich dachte auch, dass der onDisconnect-Handler dafür nicht ideal ist, da sich ein Benutzer von mehreren Geräten in sein Konto einloggen kann und beispielsweise nur ein Gerät die Internetverbindung verliert. Sagen Sie mir, Firebase berücksichtigt die Anzahl der Verbindungen pro Benutzer. Wenn ja, wo finden Sie Informationen zur Verwendung? – Alexander

+0

Das [Presence-Beispiel in der Dokumentation] (https://firebase.google.com/docs/database/ios/offline-capabilities#section-sample) verfolgt genau aus diesem Grund mehrere Verbindungen pro Benutzer. –

Antwort

0

I eine Cloud-Funktion gemacht das zählt die Anzahl der angeschlossenen Geräte, wenn die Anzahl der angeschlossenen Geräte 0 ist, dann setze ich den Wert isOnline = false und setze den 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]); 
     } 
    });