简体   繁体   English

从 Firebase 检索通知类型时出现问题

[英]Issues retrieving notificationTypes from Firebase

I have a bit of a lengthy question, So I apologize in advance I will try to illustrate this to the best of my abilities.我有一个很长的问题,所以我提前道歉,我会尽力说明这一点。 I am trying to establish a notifications view controller that calls different types of data from Firebase and sets different notification types.我正在尝试建立一个通知视图控制器,它从 Firebase 调用不同类型的数据并设置不同的通知类型。

正确的图像

In the image above, this is how the cells should look when a user sends a notification to firebase.在上图中,这是当用户向 firebase 发送通知时单元格的外观。 The user associated with that specific notification type as called and posted onto the screen.与该特定通知类型相关联的用户被调用并发布到屏幕上。

正确的 OddJobs 数据结构。

In the firebase structure, We see that all of the information Stored is saved under the UID of the user in the first picture and is set under that specific users notification to show who is sending them a notification which is correct.在 firebase 结构中,我们看到存储的所有信息都保存在第一张图片中用户的 UID 下,并设置在该特定用户通知下,以显示谁向他们发送了正确的通知。 These users names and images show perfectly as well as the image on the right.这些用户名和图像与右侧的图像一样完美显示。

The code I use to save this information is below,我用来保存这些信息的代码如下,

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

And below is how I retrieve this information and store it onto the Notifications View controller.下面是我如何检索此信息并将其存储到通知视图控制器中。

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

    })
 }
}

} }

Now that I got the correct way to setup up and show out of the way, I will show my enum and how I am distinguishing the different types of calls from firebase.现在我得到了正确的设置和展示方式,我将展示我的枚举以及我如何区分来自 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
        }
    }
}
 }

Above is the different types of notifications to be set.以上是要设置的不同类型的通知。

Now, My issue is If I call a different notification type, such as .accepted, the information calls in a very different way.现在,我的问题是,如果我调用不同的通知类型,例如 .accepted,则信息会以非常不同的方式调用。

不正确

The image above seems correct, However, the name and image are incorrect.上图看似正确,但名称和图像不正确。 it should be from the user ZacheryWilcox instead of Cjbwjdhbe.它应该来自用户 ZacheryWilcox 而不是 Cjbwjdhbe。 the user Cjbwjdhbe is the current user and the user who should be receing a notification from Zacherywilcox.用户 Cjbwjdhbe 是当前用户,也是应该从 Zacherywilcox 接收通知的用户。 not from itself.不是来自自身。

In firebase, the information is saved as在firebase中,信息保存为

不确定我是否正确

the code I use to save this information is below我用来保存此信息的代码如下

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

When the type .accepted is being used to differentiate what notificationType is being called, the user who sent the notification is not being set correctly and I have no idea what is the reasoning behind this.当使用 .accepted 类型来区分正在调用的通知类型时,发送通知的用户设置不正确,我不知道这背后的原因是什么。 The correct user that is sending this information over is Zacherywilcox, and that users image and name should be set to the user's notification screen.发送此信息的正确用户是 Zacherywilcox,该用户的图像和名称应设置为用户的通知屏幕。 not the user Cjbe... I was wondering if anyone could help me fix these issues.不是用户 Cjbe...我想知道是否有人可以帮助我解决这些问题。 Thank you in advance.先感谢您。 I'm starting to think that the way I am saving the users information when accepting the user is incorrect.我开始认为我在接受用户时保存用户信息的方式是不正确的。

When I am fetchingNotifications(), is it possible that since calling当我 fetchingNotifications() 时,是否有可能因为调用

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

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

has an effect on whats going on?对正在发生的事情有影响吗? if so, Is there a way to differentiate between what notificationType is being called and fetch what notifications has been called with their respective users?如果是这样,有没有办法区分正在调用的通知类型并获取各自用户调用的通知?

Just update your code to:只需将您的代码更新为:

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

This will solve your problem.这将解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM