从 Firebase 检索 notificationTypes 的问题

Issues retrieving notificationTypes from Firebase

我的问题有点冗长,所以我提前道歉,我会尽我所能来说明这一点。我正在尝试建立一个通知视图控制器,它从 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 用于区分调用的是什么 notificationType 时,发送通知的用户设置不正确,我不知道这背后的原因是什么。发送此信息的正确用户是 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 { 

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

只需将您的代码更新为:

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

这将解决您的问题。