Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
496 views
in Technique[技术] by (71.8m points)

ios - Swift - How Can I use 'shouldChangeTextInRange' with Firebase for real time searching?

I wonder that how creating Firebase matchesRegex query and listing current results using shouldChangeTextInRange.

I have did it before in Parse for searching username or user fullname in Parse Cloud. If someone shed light my path to do it in Firebase, it would be great.

// search updated
func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

    // find by username
    let usernameQuery = PFQuery(className: "_User")
    usernameQuery.whereKey("username", matchesRegex: "(?i)" + searchBar.text!)
    usernameQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error:NSError?) -> Void in

        if error == nil {

            // if no objects are found according to entered text in username column, find by fullname
            if objects!.isEmpty {

                let fullnameQuery = PFUser.query()
                fullnameQuery?.whereKey("fullname", matchesRegex: "(?i)" + self.searchBar.text!)
                fullnameQuery?.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in

                    if error == nil {

                        // clean up
                        self.usernameArray.removeAll(keepCapacity: false)
                        self.avaArray.removeAll(keepCapacity: false)

                        // found related objects
                        for object in objects! {
                            self.usernameArray.append(object.objectForKey("username") as! String)
                            self.avaArray.append(object.objectForKey("avatar") as! PFFile)
                        }

                        // reload
                        self.tableView.reloadData()

                    }

                })

            }

        }

        // clean up
        self.usernameArray.removeAll(keepCapacity: false)
        self.avaArray.removeAll(keepCapacity: false)

        // found related objects
        for object in objects! {
            self.usernameArray.append(object.objectForKey("username") as! String)
            self.avaArray.append(object.objectForKey("avatar") as! PFFile)
        }

        // reload
        self.tableView.reloadData()

    }

    return true

}

Update 1:

I couldn't do it using same parent name, snap.value didn't give me response, even not compile. So I have tried to do two separate parent node like that: firebase screen shot link

I'm getting indexOn security warning for each letter stroke first_name subnodes on xcode console:

[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/T" at /people_spell to your security rules for better performance

[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/Te" at /people_spell to your security rules for better performance

... much more times

I have tried these security rules it didn't solve these problems. It doesn't encompass each subnodes. How Can I provide this?

"people_spell": {
      ".read": "auth !== null",
      ".write": "auth !== null",
      ".indexOn": "first_name"
    },
"people": {
      ".read": "auth !== null",
      ".write": "auth !== null",
      ".indexOn": "first_name"
}

I'm using these lines of codes:

let peopleSpellRef = Firebase(url: "https://sampleproject.firebaseio.com/people_spell")
let peopleRef = Firebase(url: "https://sampleproject.firebaseio.com/people")

func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {

   self.usernameArray.removeAll(keepCapacity: false)

   peopleSpellRef.queryOrderedByChild("first_name/(searchBar.text!)").queryEqualToValue(true)
    .observeEventType(.Value, withBlock: { snapshot in

        let enumerator = snapshot.children
        while let rest = enumerator.nextObject() as? FDataSnapshot {

            peopleRef.childByAppendingPath("(rest.key)").observeEventType(.Value, withBlock: { snapshot in

                self.usernameArray.removeAll(keepCapacity: false)

                let str: String = (snapshot.value.objectForKey("first_name")) as! (String)
                print(str)
                self.usernameArray.append(str)
                self.userkeyArray.append(snapshot.key)

                self.tableView.reloadData()
            })
        }


        self.usernameArray.removeAll(keepCapacity: false)
        self.tableView.reloadData()

    })

return true
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...