8

I'm trying to retrieve specific data from just the currently logged in user. My data in my database looks like this:

enter image description here

For example, I want to just grab the full_name and save it in a variable userName. Below is what I'm using to grab my data

ref.queryOrderedByChild("full_name").queryEqualToValue("userIdentifier").observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
            print(snapshot.value)
            // let userName = snapshot.value["full_name"] as! String
        })

Unfortunately, this is what my console prints.

enter image description here

I would appreciate any help :) Thank you!

adolfosrs
  • 9,286
  • 5
  • 39
  • 67
Tim
  • 2,221
  • 6
  • 22
  • 43

6 Answers6

14

It gives you that warning message indexOn because you are doing a query.

you should define the keys you will be indexing on via the .indexOn rule in your Security and Firebase Rules. While you are allowed to create these queries ad-hoc on the client, you will see greatly improved performance when using .indexOn

As you know the name you are looking for you can directly go to that node, without a query.

    let ref:FIRDatabaseReference! // your ref ie. root.child("users").child("stephenwarren001@yahoo.com")

    // only need to fetch once so use single event

    ref.observeSingleEventOfType(.Value, withBlock: { snapshot in

        if !snapshot.exists() { return }

        //print(snapshot)

        if let userName = snapshot.value["full_name"] as? String {
            print(userName)
        }
        if let email = snapshot.value["email"] as? String {
            print(email)
        }

        // can also use
        // snapshot.childSnapshotForPath("full_name").value as! String
    })
DogCoffee
  • 19,820
  • 10
  • 87
  • 120
  • xcode suggested to me to add a "!" after value which I'm not sure is what we should be doing... in fact that might be what is causing it to crash(?) – Tim Jun 11 '16 at 04:12
  • its a force unwrap of an optional - if that value does not exist it will crash. – DogCoffee Jun 11 '16 at 04:30
  • Also depending on your model design you may get back multiple snapshots. So then you would use snapshot.children and loop through them all. This tutorial is good for these basics https://www.raywenderlich.com/109706/firebase-tutorial-getting-started - the firebase starter guide is also very very good! https://firebase.google.com/docs/ios/setup – DogCoffee Jun 11 '16 at 04:35
  • should I be force unwrapping it? I suspect that I shouldn't be since everyone has been writing it without the "!". Xcode won't build unless i force unwrap value – Tim Jun 11 '16 at 07:57
  • I'd be creating a struct, i.e. Person - passing in the snapshot and then dealing with the info within the snapshot. Do what the complier suggests to get it tot run. Force unwrap is ok if you know its not going to be nil. – DogCoffee Jun 11 '16 at 08:30
  • Hm it still doesn't seem to the trick for me and I also tried the comment (snapshot.childSnapshotForPath("full_name").value as! String) and I get the error "Could not cast value of type 'NSNull' to 'NSString'). I tried looking through the tutorial link too but I couldn't find specifically how to retrieve certain data :-( – Tim Jun 11 '16 at 09:53
  • sorry for all of these questions – Tim Jun 11 '16 at 10:26
  • No worries - bit by bit you'll understand more about firebase. Look at rays tutorials i posted before will help you out a lot. – DogCoffee Jun 12 '16 at 00:43
  • What's the Swift 3 way of doing this? `snapshot.value["key"]` doesn't seem to work anymore – winston Sep 08 '16 at 22:16
7

Swift 4

let ref = Database.database().reference(withPath: "user")
    ref.observeSingleEvent(of: .value, with: { snapshot in

        if !snapshot.exists() { return }

        print(snapshot) // Its print all values including Snap (User)

        print(snapshot.value!)

        let username = snapshot.childSnapshot(forPath: "full_name").value
        print(username!)

    })
Khawar Islam
  • 2,556
  • 2
  • 34
  • 56
  • Should look something like this in the current version let ref = Database.database().reference() let userID = Auth.auth().currentUser?.uid ref.child("Users").child(userID ?? "").observeSingleEvent(of: .value, with: { (snapshot) in }) – Daisy R. Mar 10 '19 at 18:48
2
{
    "rules": {
         "tbl_name": {
            ".indexOn": ["field_name1", "field_name2"]
         },
    ".read": true,
    ".write": true
    }
}

You can apply indexOn on any field. Add this json in rules security and rules tab. Hope this works for you. :)

Roshni
  • 71
  • 5
2

It retrieves logged in user data:

let ref = FIRDatabase.database().reference(fromURL: "DATABASE_URl")
let userID = FIRAuth.auth()?.currentUser?.uid
let usersRef = ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot)
urvashi bhagat
  • 1,123
  • 12
  • 15
2
let ref = Database.database().reference().child("users/stephenwarren001@yahoo.com")


    ref.observeSingleEvent(of: .value, with: { (snap : DataSnapshot)  in

        print("\(String(describing:  snap.value))")


    }) { (err: Error) in


        print("\(err.localizedDescription)")

    }
Ranjan
  • 95
  • 9
  • 4
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. – Melebius Mar 29 '18 at 12:35
0
    var refDatabase = DatabaseReference()

    refDatabase = Database.database().reference().child("users");
 let refUserIdChild = refDatabase.child("stephenwarren001@yahoo.com")
                    
                    refUserIdChild.observeSingleEvent(of: .value, with: { snapshot in

                        if !snapshot.exists() { return }

                        print(snapshot) // Its print all values including Snap (User)

                        print(snapshot.value!)
                        

                    if let tempDic : Dictionary = snapshot.value as? Dictionary<String,Any>
                    {
                           
                            if let userName = tempDic["full_name"] as? String {
                                  self.tfName.text = userName

                              }

                            if let email = tempDic["email"] as? String {
                                    self.tfEmail.text  = email

                              }

                           
                    }


                    })
                    
Davender Verma
  • 503
  • 2
  • 12