Issues retrieving notificationTypes from Firebase

Published

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.

Correct image

In the image above, this is how the cells should look when a user sends a notification to firebase. The user associated with that specific notification type as called and posted onto the screen.

Correct OddJobs Data structure.

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. 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.

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.

incorrect

The image above seems correct, However, the name and image are incorrect. it should be from the user ZacheryWilcox instead of Cjbwjdhbe. the user Cjbwjdhbe is the current user and the user who should be receing a notification from Zacherywilcox. not from itself.

In firebase, the information is saved as

not sure if im correct

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. 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. not the user Cjbe… I was wondering if anyone could help me fix these issues. 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

   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?

Source: Ios

Published
Categorised as firebase, firebase-realtime-database, ios, notifications, xcode

Answers

Leave a Reply

Your email address will not be published. Required fields are marked *

Still Have Questions?


Our dedicated development team is here for you!

We can help you find answers to your question for as low as 5$.

Contact Us
faq