我想知道如何创建 Firebase匹配Regsexex查询 并使用 shouldChangeTextInRange 列出当前结果 。
我之前在Parse中做到了,它用于在Parse Cloud中搜索用户名或用户全名。如果有人阐明了我在Firebase中执行此操作的方法,那将是很棒的。
// 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 }
更新1:
我不能使用相同的父名称来完成它,snap.value并没有给我响应,甚至没有编译。因此,我尝试像这样做两个单独的父节点:firebase屏幕截图链接
我在xcode控制台上收到 每个笔画 first_name子节点的 indexOn安全警告 : __
[Firebase] 使用未指定的索引。考虑将/ people_spell上的“ .indexOn”:“ first_name / T”添加到安全规则中,以获得更好的性能 [Firebase] 使用未指定的索引。考虑将/ people_spell中的“ .indexOn”:“ first_name / Te”添加到您的安全规则中,以获得更好的性能 …更多次
[Firebase] 使用未指定的索引。考虑将/ people_spell上的“ .indexOn”:“ first_name / T”添加到安全规则中,以获得更好的性能
[Firebase] 使用未指定的索引。考虑将/ people_spell中的“ .indexOn”:“ first_name / Te”添加到您的安全规则中,以获得更好的性能
…更多次
我尝试过这些安全规则, 但并不能解决这些问题。它不包含每个子节点。我该如何提供?
"people_spell": { ".read": "auth !== null", ".write": "auth !== null", ".indexOn": "first_name" }, "people": { ".read": "auth !== null", ".write": "auth !== null", ".indexOn": "first_name" }
我正在使用以下代码行:
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 }
这不是Firebase的工作方式,您不能直接在Firebase中对子字符串进行“实时搜索”。但是,您可以格式化要搜索的Firebase数据,还有其他两种方法也可以实现目标。
一个很简单:将数据从Firebase加载到数组中,然后通过该数组进行NSPredicate搜索(或其他方法)。
另一个是查询完整字符串很容易。只要将文本分成要搜索的块:
people person_0 first_name: "Ted" last_name: "Stryker" position: "sitting down and facing front" person_1 first_name: "Teddy"
您可以在first_name中搜索“ Ted”,或在last_name中搜索“ Stryker”,但不能在位置搜索“ front”。
现在,解决方法和要记住的磁盘空间很便宜。
可以创建一个节点,使您可以通过多种方式搜索内容
people person_0 first_name //First name is Ted from above T: true Te: true Ted: true ed: true d: true e: true person_1 first_name //First name is Teddy from above T: true Te: true Ted: true etc
通过这种结构,我们可以找到所有以Ted开头的名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true) .observeEventType(.Value, withBlock: { snapshot in for child in snapshot.children { print(child.value) } })
可以执行其他搜索;搜索所有包含e或Te等的名字。
如果纯粹是这种情况,您正在搜索以在文本字段中执行自动填充(例如),则按击键一次对firebase进行ping操作将无法正常工作。
将Firebase中的数据加载到数组或字典(或其他内容)中可能是最好的解决方案。