Dealing with memory usage due to high element count in Firebase query

前端 未结 1 1312
温柔的废话
温柔的废话 2020-12-07 06:08

I\'m writing code that is appending elements from firebase to an array to perform a simple search using a textfield.

The code for the method is below:



        
1条回答
  •  遥遥无期
    2020-12-07 06:47

    It appears the question is

    "How can I query for a value contained in a child node?"
    

    Given a structure similar to the original

    "events" : {
      "CCDS" : {
        "attend:count" : 1,
        "event:imageURL" :"someURL",
        "event:name" : "Center City District Sips"
      "MIA" : {
        "attend:count" : 1,
        "event:imageURL" : "someURL",
        "event:name" : "Made In America"
    

    a Firebase query would return the node you want.

    If the user typed in Made In America and tapped the search button here's the query to return that node in a snapshot.

    let searchString = "Made In America"
    let ref = self.ref.child("events")
    let query = ref.queryOrdered(byChild: "event:name").queryEqualTo(searchString)
    query.observeSingleEvent(of: .value, with: { (snapshot) in
        for child in snapshot.children {
            let snap = child as! DataSnapshot
            let eventDict = snap.value as! [String: Any]
            let attendCount = eventDict["attend:count"] as! String
            let url = eventDict["event:imageURL"} as! String
        }
    })
    

    If you want to do a partial string match, where the user could type in just a few characters like Made the code is similar but you need to let firebase return all of the matches starting with Made...

    The query would look like this

    let startString = "Made"
    let endString = "Made" + "\\uf8ff"
    let query = ref.queryOrdered(byChild: "event:name")
                            .queryStarting(atValue: startString)
                            .queryEnding(atValue: endString")
    

    The "\uf8ff" is a character at a very high code level in Unicode - because of that it encompasses all of the preceeding characters.

    However, querying 'on the fly' can create an unresponsive or sluggish UI so it's not recommended.

    An alternative is to create a seperate node that contains a lot less info and contains the elements the user would search for and a reference to the event node.

    So the main node containing all the data looks like this

    "events" : {
      "-uyuh8s8j8jsdas" : {
        "event": "CCDS"
        "attend:count" : 1,
        "event:imageURL" : "someURL",
      "-y88jsijsijjids" : {
        "event": "MIA"
        "attend:count" : 1,
        "event:imageURL" : "someURL",
    

    and a 'smaller' node would look like this

       events_for_searching
           -uyuh8s8j8jsdas
             event:name: "Center City District Sips"
           -y88jsijsijjids
             event:name: "Made In America"
    

    With this, you could load all of the nodes from the events_for_searching into an array (then filter the array as the user types) which would make the UI very responsive and when the user selects a name, you can then use the key from that node as a reference to load the data from the events node via an observeSingleEvent function.

    EDIT

    In response to a comment, I wanted to add a bit more detail in code.

    Here's my structure

      "events" : {
        "event_0" : {
          "event:name" : "An Event"
        },
        "event_1" : {
          "event:name" : "Made In America"
        }
      },
    

    and the code to query for event:name: Made In America

    let searchString = "Made In America"
    let ref = self.ref.child("events")
    let query = ref.queryOrdered(byChild: "event:name").queryEqual(toValue: searchString)
    
    query.observeSingleEvent(of: .value, with: { (snapshot) in
        guard let dictionary = snapshot.value as? [String: Any] else{
            print(snapshot.value)
            return
        }
        print(snapshot.value)
    }) { (err) in
        print("Failed to fetch event data", err)
    }
    

    and the output

    Optional({
        "event_1" =     {
            "event:name" = "Made In America";
        };
    })
    

    0 讨论(0)
提交回复
热议问题