用户在线状态不会自动更新

时间:2018-07-26 09:35:29

标签: swift firebase firebase-realtime-database

我有一个运行中的具有在线/离线状态的Firebase聊天应用程序,我只想知道如何在不重新加载表视图的情况下获取此数据。 当用户离线时,我必须刷新视图以注意到更改。

还有如何在不重新加载视图的情况下更改导航字幕视图

我的用户在线和离线方法

func userOnline(UserId: String){
    let uid = Auth.auth().currentUser?.uid
    let myConnectionRef = 
 Database.database().reference().child("Users").child(UserId)
    myConnectionRef.child("online").setValue(true)
   myConnectionRef.child("last_online").setValue(Date().timeIntervalSince1970)
    myConnectionRef.child("last_online").setValue(NSNumber(value: Int(NSDate().timeIntervalSince1970)))

}

func userOffline(UserId: String){
    let myConnectionRef = Database.database().reference().child("Users").child(UserId)
    myConnectionRef.child("online").setValue(false)
    myConnectionRef.child("last_online").setValue(Date().timeIntervalSince1970)

    myConnectionRef.child("last_online").setValue(NSNumber(value: Int(NSDate().timeIntervalSince1970)))

}


func checkUserStatus(userid:String){
    let myConnectionRef = Database.database().reference().child("Users").child(userid)
    myConnectionRef.child("online").setValue(true)
    myConnectionRef.child("typing").setValue(false)

    myConnectionRef.child("last_online").setValue(NSNumber(value: Int(NSDate().timeIntervalSince1970)))

    // Observe For User logged in or logged out
    myConnectionRef.observe(.childChanged) { (snapshot) in
        guard let connected = snapshot.value as? Bool, connected else {return}
    }
}

我使用if else语句来更改单元格。detailtext

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
    let user = users[indexPath.row]
    cell.textLabel?.text = user.userName
    let uid = Auth.auth().currentUser?.uid

    if (user.online as? Bool)!{
        cell.detailTextLabel?.font = UIFont.italicSystemFont(ofSize: 12)
        cell.detailTextLabel?.textColor = UIColor.flatGreen()
        cell.detailTextLabel?.text = "online"
    }
    else {
         let date = user.last_online!
         let seconds = user.last_online?.doubleValue
         let timeStamp = NSDate(timeIntervalSince1970: seconds!)
         let dateFormatter = DateFormatter()
         dateFormatter.dateFormat = "E, d MMM yy hh:mm:a"
         cell.detailTextLabel?.font = UIFont.italicSystemFont(ofSize: 12)
         cell.detailTextLabel?.textColor = UIColor.lightGray
         cell.detailTextLabel?.text = ("Last Seen: \(dateFormatter.string(from: timeStamp as Date))")
    }



    if let profileImageUrl = user.profileImageUrl {
        cell.profileImageView.loadImageFromCache(urlString: profileImageUrl)

    }
    return cell
}

但是我必须刷新tableview。 有没有一种方法可以自动进行此更改

2 个答案:

答案 0 :(得分:0)

如果要脱机使用,则必须存储数据。

  Database.database().isPersistenceEnabled = true

还要保持数据同步

    let scoresRef = Database.database().reference(withPath: "scores")
scoresRef.keepSynced(true)

用于离线使用数据

    let scoresRef = Database.database().reference(withPath: "scores")
scoresRef.queryOrderedByValue().queryLimited(toLast: 4).observe(.childAdded) { snapshot in
  print("The \(snapshot.key) dinosaur's score is \(snapshot.value ?? "null")")
}

有关更多信息,请参见Firebase offline capability

答案 1 :(得分:0)

首先,Firebase具有一个非常出色的Cloud Functions,它可以处理数据库更改,例如发送推送通知。您可以检查文档,仔细阅读并设置node.js平台来编写函数。

设置后,将编写以下代码以在index.js文件中发送推送通知:

'use strict';
const functions = require('firebase-functions');

// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
// exports.helloWorld = functions.https.onRequest((request, response) => {
//  response.send("Hello from Firebase!");
// });
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);

exports.sendNotification = functions.https.onCall((data, context) => {

const tokens = [data.token];

const payload = {
          notification: {
            title: data.title,
            body: data.text,
          },
          data: data.data

        };
        return admin.messaging().sendToDevice(tokens, payload).then(() => {

  // Returning the sanitized message to the client.

       });
});

好的,现在您可以准备发送部件了。现在其他用户将收到它。

因此,在AppDelegate中:

// This method will be called when app received push notifications in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("received push notification whilst in the foreground")

        let msg = notification.request.content

        if let group = msg.userInfo["chat"] as? String {
                let showingVC = UIApplication.topViewController()
                if showingVC is GroupChatVC {

                //here you will get the online status so update the status label by using the NSNotificationCenter
                    return // hide notification
                }

        }

        completionHandler(UNNotificationPresentationOptions.alert)
    }

ViewControlleruserOnline()分别写在的userOffline()中:

    static var functions = Functions.functions()

func userOnline(UserId: String){
    let uid = Auth.auth().currentUser?.uid
    let myConnectionRef = 
 Database.database().reference().child("Users").child(UserId)
    myConnectionRef.child("online").setValue(true)
   myConnectionRef.child("last_online").setValue(Date().timeIntervalSince1970)
    myConnectionRef.child("last_online").setValue(NSNumber(value: Int(NSDate().timeIntervalSince1970)))
    self.send(toUserID: receiverUserID, title: Chat Status, text: msg, data: ["chat": "online"])

}

func userOffline(UserId: String){
    let myConnectionRef = Database.database().reference().child("Users").child(UserId)
    myConnectionRef.child("online").setValue(false)
    myConnectionRef.child("last_online").setValue(Date().timeIntervalSince1970)

    myConnectionRef.child("last_online").setValue(NSNumber(value: Int(NSDate().timeIntervalSince1970)))
    self.send(toUserID: receiverUserID, title: Chat Status, text: msg, data: ["chat": "offline"])

}

static func send(toUserID: String, title:String, text: String, data: [String: Any]? = nil) {

        var value = Dictionary<String, Any>()
        value["type"] = "notification"
        value["to"] = toUserID
        value["text"] = text
        value["title"] = title
        if data != nil { value["data"] = data }
        Database.database().reference().ref("users/\(toUserID)/private/fcm").observeSingleEvent(of: .value, with: { (namesnapshot) in
            if namesnapshot.exists() {
                let token = namesnapshot.value as! String
                print("FOUND \(token)")
                value["token"] = token
                functions.httpsCallable("sendNotification").call(value) { (result, error) in

                    if let text = (result?.data as? [String: Any])?["text"] as? String {
                        print("Result \(text)")
                    }
                }
            }
        })

    }

希望您了解FCMNSNotificationCenter部分。您到处都可以找到这些教程。