从 Firebase 检索 notificationTypes 的问题

Posted

技术标签:

【中文标题】从 Firebase 检索 notificationTypes 的问题【英文标题】:Issues retrieving notificationTypes from Firebase 【发布时间】:2020-02-04 22:49:47 【问题描述】:

我有一个很长的问题,所以我提前道歉,我会尽力说明这一点。我正在尝试建立一个通知视图控制器,从 Firebase 调用不同类型的数据并设置不同的通知类型。

在上图中,这是用户向 Firebase 发送通知时单元格的外观。与调用并发布到屏幕上的特定通知类型相关联的用户。

在 firebase 结构中,我们看到存储的所有信息都保存在第一张图片中用户的 UID 下,并设置在该特定用户通知下,以显示谁在向他们发送正确的通知。这些用户名和图像与右侧的图像一样完美地显示出来。

我用来保存这些信息的代码如下,

    fileprivate func saveSwipeToDataBase(didLike: Any) 
    let swipeDate = Int(NSDate().timeIntervalSince1970)
    guard let uid = Auth.auth().currentUser?.uid else  return 

    guard let cardUID = topCardView?.cardViewModel.uid else  return 

    let documentData = ["workerId": uid,
                        "didLike": didLike,
                        "checked": 0,
                        "Swipe Date": swipeDate,
                        "type": SWIPE_INT_VALUE,
                        "posterId" : cardUID] as [String : Any]

    self.postJobNotificationsIntoDatabseWithUID(uid: cardUID, values: documentData as [String : AnyObject])


private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) 
    let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
        let usersReference = ref.child("notifications").child(uid).childByAutoId()
        usersReference.setValue(values, withCompletionBlock:  (err, ref) in
        if err != nil 
            print("error saving data into firebase")
            return
        
    )

下面是我如何检索这些信息并将其存储到通知视图控制器中。

 func fetchNotifications() 

guard let currentUID = Auth.auth().currentUser?.uid else  return 
NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value)  (snapshot) in
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else  return 
    print(dictionary)

    for (_, postingRawData) in dictionary 
guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else  continue 
guard let uid = postingDictionary["workerId"] as? String else  continue 

    Database.fetchUser(with: uid, completion:  (user) in
        if let postId = postingDictionary["posterId"] as? String 

            Database.fetchPoster(with: postId, completion: (poster) in

                let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
                self.notifications.append(notification)
                self.handleSortNotification()

            )

         else 
            let notification = userNotifications(user: user, dictionary: postingDictionary)
            self.notifications.append(notification)
            self.handleSortNotification()
        

    )
 

现在我已经找到了正确的设置和展示方法,我将展示我的枚举以及我如何区分来自 firebase 的不同类型的调用。

class userNotifications 

// MARK: - establish notificationTypes

enum NotificationType: Int, Printable 

    case swipe
    case accepted
    case confirmed
    case completed
    case pay

    var description: String 
        switch self 
        case .swipe: return " swiped on your Job "
        case .accepted: return " accepted you to complete the job, "
        case .confirmed: return " confirmed the job"
        case .completed: return " completed the job"
        case .pay: return " pay for completed"

        
    

    init(index: Int) 
        switch index 
        case 0: self = .swipe
        case 1: self = .accepted
        case 2: self = .confirmed
        case 3: self = .completed
        case 4: self = .pay

        default: self = .swipe
        
    


// MARK: - access firebaseData

var creationDate: Date!
var timeDate: Date!
var uid: String!
var fromId: String?
var workerId: String?
var user: User!
var poster: Poster!
var type: Int?
var notificationType: NotificationType!
var didCheck = false

init(user: User? = nil, poster: Poster? = nil, dictionary: Dictionary<String, AnyObject>) 

    self.user = user

    if let poster = poster 
        self.poster = poster
    

    if let swipeDate = dictionary["Swipe Date"] as? Double 
        self.creationDate = Date(timeIntervalSince1970: swipeDate)
    

    if let createDate = dictionary["creationDate"] as? Double 
               self.creationDate = Date(timeIntervalSince1970: createDate)
           

    if let swipeDate = dictionary["time&date"] as? Double 
            self.timeDate = Date(timeIntervalSince1970: swipeDate)
        

    if let type = dictionary["type"] as? Int 
        self.notificationType = NotificationType(index: type)
    

    if let uid = dictionary["uid"] as? String 
        self.uid = uid
    

    if let fromId = dictionary["fromId"] as? String 
        self.fromId = fromId
    

    if let workerId = dictionary["workerUID"] as? String 
              self.workerId = workerId
          

    if let checked = dictionary["checked"] as? Int 
        if checked == 0 
            self.didCheck = false
         else 
            self.didCheck = true
        
    

 

以上是要设置的不同类型的通知。

现在,我的问题是,如果我调用不同的通知类型,例如 .accepted,则信息调用的方式非常不同。

上面的图片看起来是正确的,但是名称和图片不正确。它应该来自用户 ZacheryWilcox 而不是 Cjbwjdhbe。用户 Cjbwjdhbe 是当前用户,也是应该从 Zacherywilcox 接收通知的用户。不是来自自身。

在firebase中,信息保存为

我用来保存这些信息的代码如下

    var workerUser: User? 

didSet 


    let name = workerUser?.name
    workerNameLabel.text = name

    let workersUID = workerUser?.uid
    workerNameLabel.text = name

    guard let profileImage = workerUser?.profileImageUrl else  return      
    workerImageView.loadImageUsingCacheWithUrlString(profileImage)


   
   

  func saveUserData() 
      let workUser = self.workerUser
      guard let uid = Auth.auth().currentUser?.uid else  return 
      let workerId = workUser?.uid

       Database.database().reference().child("users").child(uid).observeSingleEvent(of: .value, with:  (snapshot) in
        guard let dictionary = snapshot.value as? [String : Any] else  return 
        let user = User(dictionary: dictionary as [String : AnyObject])
        workUser?.uid = snapshot.key

        self.datePicker.datePickerMode = UIDatePicker.Mode.date
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MMMM dd yyyy/ hh:mm a"
        let selectedDate = dateFormatter.string(from: self.datePicker.date)
        let creationDate = Int(NSDate().timeIntervalSince1970)
        print(selectedDate)

        let docData: [String: Any] = [

                       "workerId": workerId!,
                       "time&date": selectedDate,
                       "posterId" : uid,
                       "creationDate": creationDate,
                       "location": user.address!,
                       "type": 1,
                       "jobPost": "someUIDString",
                       "checked": 0,

                   ]

        self.postJobNotificationsIntoDatabseWithUID(uid: workerId!, values: docData as [String : AnyObject])

     , withCancel:  (err) in
        print("attempting to load information")
        )

        print("Finished saving user info")
        self.dismiss(animated: true, completion: 
            print("Dismissal complete")
        )


    

 private func postJobNotificationsIntoDatabseWithUID(uid: String, values: [String: AnyObject]) 
    let ref = Database.database().reference(fromURL: "https://oddjobs-b131f.firebaseio.com/")
        let usersReference = ref.child("notifications").child(uid).childByAutoId()
        usersReference.setValue(values, withCompletionBlock:  (err, ref) in
        if err != nil 
            print("error saving data into firebase")
            return
        
    )

当使用 .accepted 类型来区分正在调用的通知类型时,发送通知的用户没有被正确设置,我不知道这背后的原因是什么。发送此信息的正确用户是 Zacherywilcox,用户的图像和名称应设置到用户的通知屏幕。不是用户 Cjbe... 我想知道是否有人可以帮助我解决这些问题。先感谢您。我开始认为我在接受用户时保存用户信息的方式不正确。

当我在 fetchingNotifications() 时,是否有可能自从调用

   guard let uid = postingDictionary["workerId"] as? String else  continue 

Database.fetchUser(with: uid, completion:  (user) in
    if let postId = postingDictionary["posterId"] as? String  

对发生的事情有影响吗?如果是这样,有没有办法区分正在调用的通知类型并获取各自用户调用的通知?

【问题讨论】:

只是对您的“通知”节点数据库结构的评论。看起来“fromid”总是与这些通知的用户 ID 键相同,因此您实际上不需要在每个通知上将其存储为“fromid”。每条通知记录将为您节省 28 个字节,您无需支付存储和数据传输费用。 【参考方案1】:

只需将您的代码更新为:

func fetchNotifications() 


    guard let currentUID = Auth.auth().currentUser?.uid else  return 
    NOTIFICATIONS_REF.child(currentUID).observeSingleEvent(of: .value)  (snapshot) in
    guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else  return 
        print(dictionary)

         let notificationId = snapshot.key

        for (_, postingRawData) in dictionary 
    guard let postingDictionary = postingRawData as? Dictionary<String, AnyObject> else  continue 
            guard let type = postingDictionary["type"] as? Int else  continue 
            guard let uid = (type == userNotifications.NotificationType.accepted.rawValue) ? postingDictionary["fromId"] as? String : postingDictionary["workerId"] as? String else  continue 

        Database.fetchUser(with: uid, completion:  (user) in
            if let postId = postingDictionary["fromId"] as? String 

                Database.fetchPoster(with: postId, completion: (poster) in

                    let notification = userNotifications(user: user, poster: poster, dictionary: postingDictionary)
                    self.notifications.append(notification)
                    self.handleSortNotification()

                )

             else 
                let notification = userNotifications(user: user, dictionary: postingDictionary)
                self.notifications.append(notification)
                self.handleSortNotification()
            
                 // NOTIFICATIONS_REF.child(currentUID).child(notificationId).child("checked").setValue(1)
        )
     
    
  

这将解决您的问题。

【讨论】:

以上是关于从 Firebase 检索 notificationTypes 的问题的主要内容,如果未能解决你的问题,请参考以下文章

从firebase检索数据到android

如何从 Firebase 检索用户数据 android

如何从 Firebase 同步检索数据?

无法从短动态链接中检索数据 - Firebase

Android:使用 ArrayList 从 Firebase 检索对象

Swift 从 Firebase 检索数据