3

I am using Firebase Realtime Database, using codable approach in swift and external library CodableFirebase. I have created model structure but when I am trying to parse values (as i am getting all values) with model structure it gives me nil. My database has keys which might I am not properly handling in nested values. Please help. Thanks

database structure snapshot attached.

database

Code:

Database.database().reference().child("users").observeSingleEvent(of: .value, with: { (snapshot) in
            guard let value = snapshot.value as? [String: Any] else { return }
            do {

                let friendList = try FirebaseDecoder().decode(Response.self, from: value)

                guard let conversationUid = value["conversationUid"] as? String,
                let friendStatus = value["friendStatus"] as? String,
                let notify = value["notify"] as? Bool,
                let phNumber = value["phoneNumber"] as? String,
                let uid = value["uid"] as? String
                else { return }


            } catch let error {
                print(error)
            }
        })

JSON:

{
  "FTgzbZ9uWBTkiZK9kqLZaAIhEDv1" : {
    "friends" : {
      "zzV6DQSXUyUkPHgENDbEjXVBj2" : {
        "conversationUid" : "-L_w2yi8gh49GppDP3r5",
        "friendStatus" : "STATUS_ACCEPTED",
        "notify" : true,
        "phoneNumber" : "+9053",
        "uid" : "zzV6DQSXUyUkPHgEZ9EjXVBj2"
      }
    },
    "lastLocation" : {
      "batteryStatus" : 22,
      "latitude" : 48.90537,
      "longitude" : 28.042,
      "timeStamp" : 1556568633477,
      "uid" : "FTgzbZ9uWkiZK9kqLZaAIhEDv1"
    },
    "profile" : {
      "fcmToken" : "fp09-Y9ZAkQ:APA91bFgGBsyFx0rtrz7roxzpE_MmuSaMc4is-XIu7j718qjRVCSHY4PvbNjL1LZ-iytaeDKviIRMH",
      "name" : "Mt Bt",
      "phoneNumber" : "+90503",
      "uid" : "FTgzbZ9uWBTkiZLZaAIhEDv1"
    }
  }

Model:

struct Response : Codable {

    let friends : Friend?
    let lastLocation : LastLocation?
    let profile : Profile?
}

struct Friend: Codable {
    let converstionUid: String?
    let friendStatus: String?
    let notify: Bool?
    let phoneNumber: String?
    let uid: String?

}

struct Profile : Codable {

    let fcmToken : String?
    let name : String?
    let phoneNumber : String?
    let uid : String?
}

struct LastLocation : Codable {

    let batteryStatus : Int?
    let latitude : Float?
    let longitude : Float?
    let timeStamp : Int?
    let uid : String?
}

Newbie
  • 360
  • 3
  • 19

1 Answers1

6

Your code is reading the entire users node, and then tries to read the conversationUid and other properties from that node. Since these properties don't exist directly under the users node, you get null.

To properly parse this JSON, you'll need to navigate the three levels of child nodes before you try to read the named properties like conversationUid.

Database.database().reference().child("users").observeSingleEvent(of: .value, with: { (snapshot) in
  for userSnapshot in snapshot.children.allObjects as! [DataSnapshot] {
    let friendsSnapshot = userSnapshot.childSnapshot(forPath: "friends")
    for friendSnapshot in friendsSnapshot.children.allObjects as! [DataSnapshot] {

      guard let value = friendSnapshot.value as? [String: Any] else { return }
      do {
        guard let conversationUid = value["conversationUid"] as? String,
        ...

The above code first loops over the first-level child nodes under /users, and it then loops over the children of the friends node for each user.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you. I have just updated my question and includes JSON data as well. Let me apply your code and let you know. – Newbie Oct 21 '19 at 14:31
  • Perfect Thank you its working. Any idea about implementing `FIRDataEventTypeChildAdded` with model because above scenario refresh all data not some `change/modified` part. – Newbie Oct 21 '19 at 15:28
  • please can you guide me how to get friends from profile? every profile has uid field which is matching with users unique key and basis of this every profile has different number of friends. – Newbie Oct 22 '19 at 12:00
  • You'll need a nested observer for that, probably using `observeSingleEvent(of: .value)`, as shown here: https://firebase.google.com/docs/database/ios/read-and-write#read_data_once – Frank van Puffelen Oct 22 '19 at 12:57
  • i try to use nested observer but not be much accurate. do you mind to help me out honestly I am really stuck with that .... – Newbie Oct 22 '19 at 14:47