Query users by name or email address using Firebase (Swift)

I’m quite new to Firebase and Swift and I’m having some trouble when it comes to querying.
So there are basically two things I’d like to do:

  1. Query my users and find only those that contain a certain String in their name (or email address) and add them to an array.
  2. Get all of my users and add them to an array.

The relevant part of my data for this question looks like this:
enter image description here

  • Cannot import Firebase in Swift app
  • how to write synchronous query call for firebase?
  • Firebase Upgrading From 2.5.1 to 3.2.1
  • Framework not found GoogleToolboxForMac
  • Retrieve Boolean array from Firebase
  • Using UpdateChildValues to delete from Firebase
  • As you can see, I’m using the simplelogin of Firebase (later I’d like too add Facebook login) and I’m storing my users by their uid.

    A part of my rules file looks like this:

    "registered_users": {
        ".read": true,
        ".write": true,
        ".indexOn": ["name"]
     }
    

    So everybody should have read and write access to this part of my data.

    I also read the “Retrieving Data” part of the Firebase iOS Guide on their website and according to that guide, my code on getting all the users names and email addresses should work, at least I think so. But it doesn’t. Here is my code:

    func getUsersFromFirebase() {
            let registeredUserRef = firebaseRef.childByAppendingPath("registered_users")
            registeredUserRef.queryOrderedByChild("name").observeSingleEventOfType(.Value, withBlock: { snapshot in
                if let email = snapshot.value["email"] as? String {
                    println("\(snapshot.key) has Email: \(email)")
                }
                if let name = snapshot.value["name"] as? String {
                    println("\(snapshot.key) has Name: \(name)")
                }
            })
        }
    

    I noticed, that in the firebase guide, they always used the type ChildAdded and not Value, but for me Value makes more sense. The output with Value is nothing and the output with ChildAdded is only one user, namely the one that is logged in right now.

    So my questions are:

    1. Can I do this query with my current data structure or do I have to get rid of storying the users by their uid?
    2. If yes, how would I have to change my code, to make it work?
    3. If no, what would be the best way to store my users and make querying them by name possible?
    4. How can I query for e.g. “muster” and get only the user simplelogin:1 (Max Mustermann)?

    I hope my description is detailed enough. Thx in advance for your help.

    Supplement:

    The weird thing is, that the “Retrieving Data” guide says, that querying and sorting the following data by height is possible.

    Data:

    enter image description here

    Querying code:
    enter image description here

    And isn’t that exactly the same that I intent to do?

    2 Solutions Collect From Internet About “Query users by name or email address using Firebase (Swift)”

    I have run into similar situations where I wanted to pull out data from child nodes.

    https://groups.google.com/d/msg/firebase-talk/Wgaf-OIc79o/avhmN97UgP4J

    The first thing I can recommend is to not think of Firebase query’s as SQL queries as they are not. They are like a light duty query.

    Secondly, you need to flatten your data if you want to query, as a query only goes one level deep (can’t really query data in child notes)

    Lastly – if you don’t want to flatten your data, one conceptual option to answer your question;

    1. If possible, ObserveSingleEventOfType:FEventTypeValue on the
      registered users node. This will read all of the registered users into a snapshot.
    2. Iterate over the snapshot and read each user into an array (as dictionary objects)
    3. Then use NSPredicate to extract an array of users that you want.

    I’ve run numerous tests and performance wise, it’s negligible unless you have thousands of users.

    Hope that helps!

    To answer your questions

    1) Yes, you can query with your current structure. A query can go 1 child deep, but not within a child’s children.

    2) If yes, how would I have to change my code, to make it work?

    Here’s a quickie that queries by a users last name:

    Firebase *usersNodeRef = your users node 'registered_users'
    FQuery *allUsersRef = [usersNodeRef queryOrderedByChild:@"lastName"];
    FQuery *specificUserRef = [allUsers queryEqualToValue:@"aLastName"];
    
    [specificUser observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *snapshot) {
    
      NSDictionary *dict = snapshot.value;
      NSString *key = snapshot.key;
    
      NSLog(@"key = %@ for child %@", key, dict);
    
    }];
    

    How can I query for e.g. “muster” and get only the user simplelogin:1 (Max Mustermann)?

    In your uses node structure, the users are store in nodes with a key.. the key is the simplelogin:1 etc. snapshot.key will reveal that. So it’s key/value pair deal…

    value = snapshot.value
    key = snapshot.key