I wonder that how creating Firebase matchesRegex query and listing current results using shouldChangeTextInRange.
我想知道如何使用shouldChangeTextInRange创建Firebase matchesRegex查询和列出当前结果。
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.
我之前在Parse中已经在Parse Cloud中搜索用户名或用户fullname。如果有人在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
}
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
我无法使用相同的父名称,snap.value没有给我回复,甚至没有编译。所以我试图做两个单独的父节点:firebase屏幕截图链接
I'm getting indexOn security warning for each letter stroke first_name subnodes on xcode console:
我在xcode控制台上为每个字母描边first_name子节点获取indexOn安全警告:
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/T" at /people_spell to your security rules for better performance
[Firebase]使用未指定的索引。考虑在/ people_spell中将“.indexOn”:“first_name / T”添加到您的安全规则中,以获得更好的性能
[Firebase] Using an unspecified index. Consider adding ".indexOn": "first_name/Te" at /people_spell to your security rules for better performance
[Firebase]使用未指定的索引。考虑在/ people_spell中将“.indexOn”:“first_name / Te”添加到您的安全规则中,以获得更好的性能
... 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
}
1 个解决方案
#1
2
This is not how Firebase works and you can't directly do a 'real time search' in Firebase for a substring. But, you can format your Firebase data to be searched and there are a couple of other methods which will also accomplish the goal.
这不是Firebase的工作原理,您无法直接在Firebase中对子字符串进行“实时搜索”。但是,您可以格式化要搜索的Firebase数据,还有其他一些方法也可以实现目标。
One is straightforward: load your data from Firebase into an array and NSPredicate search (or other methods) through the array.
一个是直截了当的:将数据从Firebase加载到数组中,并通过数组进行NSPredicate搜索(或其他方法)。
Another is that query'ing for full strings is easy; as long as the text is broken up into the chunks you want to search for:
另一个是查询完整字符串很容易;只要文本被分解为您要搜索的块:
people
person_0
first_name: "Ted"
last_name: "Stryker"
position: "sitting down and facing front"
person_1
first_name: "Teddy"
You can search for 'Ted' in first_name or 'Stryker' in last_name but you cannot search for 'front' in position.
您可以在first_name中搜索“Ted”或在last_name中搜索“Stryker”,但不能在位置搜索“front”。
Now the workaround and keep in mind disk space is cheap.
现在解决方法并记住磁盘空间很便宜。
A node can be created that will let you search for stuff in a variety of ways
可以创建一个节点,让您以各种方式搜索内容
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
With this structure we can find all first names that start with Ted
通过这种结构,我们可以找到以Ted开头的所有名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
print(child.value)
}
})
Other searches can be performed; searching for all first names that contain e or Te etc.
可以执行其他搜索;搜索包含e或Te等的所有名字。
If this is purely a situation where you are searching to perform an autofill in a text field (for example) pinging firebase on a keystroke by keystroke basis isn't going to work well.
如果这纯粹是你正在搜索在文本字段中执行自动填充的情况(例如),按键击键击击击火基不能很好地工作。
Loading the data from Firebase into an array, or dictionary (or whatever) will probably be your best solution.
将Firebase中的数据加载到数组或字典(或其他)中可能是您的最佳解决方案。
#1
2
This is not how Firebase works and you can't directly do a 'real time search' in Firebase for a substring. But, you can format your Firebase data to be searched and there are a couple of other methods which will also accomplish the goal.
这不是Firebase的工作原理,您无法直接在Firebase中对子字符串进行“实时搜索”。但是,您可以格式化要搜索的Firebase数据,还有其他一些方法也可以实现目标。
One is straightforward: load your data from Firebase into an array and NSPredicate search (or other methods) through the array.
一个是直截了当的:将数据从Firebase加载到数组中,并通过数组进行NSPredicate搜索(或其他方法)。
Another is that query'ing for full strings is easy; as long as the text is broken up into the chunks you want to search for:
另一个是查询完整字符串很容易;只要文本被分解为您要搜索的块:
people
person_0
first_name: "Ted"
last_name: "Stryker"
position: "sitting down and facing front"
person_1
first_name: "Teddy"
You can search for 'Ted' in first_name or 'Stryker' in last_name but you cannot search for 'front' in position.
您可以在first_name中搜索“Ted”或在last_name中搜索“Stryker”,但不能在位置搜索“front”。
Now the workaround and keep in mind disk space is cheap.
现在解决方法并记住磁盘空间很便宜。
A node can be created that will let you search for stuff in a variety of ways
可以创建一个节点,让您以各种方式搜索内容
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
With this structure we can find all first names that start with Ted
通过这种结构,我们可以找到以Ted开头的所有名字
peopleRef.queryOrderedByChild("first_name/Ted").queryEqualToValue(true)
.observeEventType(.Value, withBlock: { snapshot in
for child in snapshot.children {
print(child.value)
}
})
Other searches can be performed; searching for all first names that contain e or Te etc.
可以执行其他搜索;搜索包含e或Te等的所有名字。
If this is purely a situation where you are searching to perform an autofill in a text field (for example) pinging firebase on a keystroke by keystroke basis isn't going to work well.
如果这纯粹是你正在搜索在文本字段中执行自动填充的情况(例如),按键击键击击击火基不能很好地工作。
Loading the data from Firebase into an array, or dictionary (or whatever) will probably be your best solution.
将Firebase中的数据加载到数组或字典(或其他)中可能是您的最佳解决方案。