adams.s
adams.s

Reputation: 195

Searching through firebase data: iOS, Swift

I wanted to know if it's possible and how you can search through firebase. My app has a textfield where you can fill in some specifications that's get 'saved' in through an array.

for example:

var arrayOfSpecs = ["13'", "Black"]

Now I want to search with 2 segmented options:

Example: Search for "black" "13inch"; the searchResults could include a MacBook with one spec: "black", but it could also include a MacBook Pro with 2 specs: "black" and "13inch", but it can not include a MacBook Air with specs: "Black", "13 inch", "Retina"

The searchResult would come in a tableview, or would store the correct names of the searchResults in array, which I would put in a UITableView

Below my database, I'll hope you understand what I'm looking for.

thanks

enter image description here

Upvotes: 4

Views: 1492

Answers (3)

Cody Weaver
Cody Weaver

Reputation: 4886

You could also use a SQL solution instead of Key-Value. Firebase is strictly a Key-Value database.

Upvotes: 0

Jay
Jay

Reputation: 35648

So start off with a products node for all products. The node name is created with childByAutoId.

products
  -abcde
    name: MacBook
    color: black
    display: retina
    port: Thunderbolt
    size: 13
  -fghij
    name: MacBook Air
    color: black
    display: standard
    port: USB
    size: 13
  -xxxxx
    name... etc etc

Then we divide up the specifications and refer back to the products in each node.

specs
  black
   13
     abcde: true
     fghij: true
   15
     xxxx: true
  grey
   13
    yyyy: true
    zzzz: true
   15
    qqqq: true
  13
     abcde: true
     fghij: true
     yyyy: true
     zzzz: true

If you want all black, 13" Macs, observeSingleEventOfType of .Value on the

specs/black/13

node which will load in the abcde, and fghij product references.

If you want to get all grey 15 inch laptops, do the same on the

specs/grey/15

node.

If you want all 13 inch laptops observe the

specs/13

node

The beauty of this is you don't need any queries at all since you know specifically what data you are after. Queries are very heavy compared to an observe event.

Another option is to compile the specs into single lines

specs
  -abcde
     black_13_retina_SSD_Thunderbolt
     13_retina_SSD_Thunderbolt
     retina_SSD_Thunderbolt
     SSD_Thunderbolt
     Thunderbolt
     .
     .
  -fgijk
     black_13_standard_SSD_USB
     13_standard_SSD_USB
     etc

Then you can easily query for all models that have SSD_Thunderbolt.

You can also query for all products that startsWith: 13_ and endsWith: 13_

You will need to put the various combinations within each spec so you could query for 13_SSD but if you only have 3 or 4 specs it's not too bad.

Remember - disk space is cheap and don't be afraid to duplicate data in different formats to get back what you want. Also, crafting a parser to read the main product, parse it and dump the specs out in their combinations is pretty simple.

Hope that helps.

Upvotes: 0

Dravidian
Dravidian

Reputation: 9945

Change your JSON Structure to

            Electroniks:{
                  Macbook:{..,
                           Specification:{
                               13inch : true,
                               black : true 
                              },
                            ...
                        },
                   iPhone:{..,
                           Specification:{
                               13inch : true,
                               black : true,
                               camera : true 
                              },
                            ...
                        },
                   iPad:{..,
                           Specification:{
                               xinch : true,
                               red : true,
                               camera : true 
                              },
                            ...
                        }
            }

I don't think you can match two node queries at once , But what you can is, you can match one specification .queryEqualToValue at a time

So a workaround would be :- retrieve all the parentNodes which have one particular Specification and then iterate through those to match your other Specification

  let parentRef = FIRDatabase.database().reference().child("Elektronics")
parentRef.queryOrderedByChild("Specification/black").queryEqualToValue(true).observeSingleEventOfType(.Value, withBlock: {(snap) in

        if let dict = snap.value as? [String:AnyObject]{

        for each in dict{

            print(each.0) //Would retrieve you every product name with colour black in specification i.e Macbook and iPhone
            print((each.1["Specification"] as! NSDictionary).count)//Number of specification
            parentRef.child("each.0").child("Specification").child("13inch").observeSingleEventOfType(.Value, withBlock: {(snapshot) in

            if snapshot.exists(){

                   print(each.0) //You found your product's with exactly 13inch and black Specification.This is their name
                   }

              })

            }
        }else{

            print(snap.ref)

          }
        })

Upvotes: 2

Related Questions