How can I create a search function for firebase firestore?
After some more creative thinking, I decided to create keywords for each document. It is not super elegant but it works. Also each "name" field is limited to X characters so I do not need to worry about the keywords field exceeding more than 20-30 individual keyword strings.
I added
var keywords: [String]?
to the StoryModel and the fields looks like this once filled in on doc creation:
And I am getting the live results with:
private lazy var storiesDataCollection = Firestore.firestore().collection("Stories")
self.storiesDataCollection
.whereField("keywords", arrayContains: self.storiesSearchText)
.limit(to: 8)
.getDocuments {}
I am not including the function that creates the keywords because I have simply not done it yet, I will edit and add it once I complete it, but for testing I just manually created the keywords in firestore. Lastly, this solution does not ignore case, the search text has to match perfectly.
EDIT: Here is the function that creates the keywords, I also added the ability to make a case matched and lowercased for better searching.
func createKeywords(name: String) {
var keywords: [String] = []
var lowercaseKeywords: [String] = []
var alreadyKeyed: String = ""
for letter in name {
if keywords.isEmpty {
keywords.append("\(letter)")
let lower = letter.lowercased()
lowercaseKeywords.append("\(lower)")
} else {
let key = alreadyKeyed + "\(letter)"
keywords.append(key)
let lower = key.lowercased()
lowercaseKeywords.append("\(lower)")
}
alreadyKeyed.append("\(letter)")
}
let allKeywords = keywords + lowercaseKeywords
self.storiesDataCollection.document("doc id goes here").updateData([
"keywords" : allKeywords
]) { error in
if let error = error {
print("Error: \(error)")
} else {
print("SUCCESS")
}
}
}
If you were to feed it a string of "Trevor's NYE Party" here is what it would give back:
["T", "Tr", "Tre", "Trev", "Trevo", "Trevor", "Trevor\'", "Trevor\'s", "Trevor\'s ", "Trevor\'s N", "Trevor\'s NY", "Trevor\'s NYE", "Trevor\'s NYE ", "Trevor\'s NYE P", "Trevor\'s NYE Pa", "Trevor\'s NYE Par", "Trevor\'s NYE Part", "Trevor\'s NYE Party", "t", "tr", "tre", "trev", "trevo", "trevor", "trevor\'", "trevor\'s", "trevor\'s ", "trevor\'s n", "trevor\'s ny", "trevor\'s nye", "trevor\'s nye ", "trevor\'s nye p", "trevor\'s nye pa", "trevor\'s nye par", "trevor\'s nye part", "trevor\'s nye party"]
note the backslashes are not actually uploaded to firestore.
grab the current users first name cloud firebase swift
As you are looping through a list of all user documents so it will show last user's firstName
on the label. You might want to show the first user as below,
if let firstUserDoc = snapshot?.documents.first {
var welcomeName = firstUserDoc["firstname"] as! String
self.welcomeLabel.text = "Hey, \(welcomeName) welcome!"
}
Or may be this for current user if uid
in the list is same as userId
,
if let currentUserDoc = snapshot?.documents.first(where: { ($0["uid"] as? String) == userId }) {
var welcomeName = currentUserDoc["firstname"] as! String
self.welcomeLabel.text = "Hey, \(welcomeName) welcome!"
}
Query Searches Swift
You'll want to use a Firestore query, instead of performing the search in your application code. With a Firestore query, the filtering is performed by the database, instead of in your application code.
The simplest way to search is:
let dbQuery = COLLECTION_USERS
.whereField("fullname", isGreaterThanOrEqualTo: query)
.whereField("fullname", isLessThanOrEqualTo: query+"\u{F7FF}")
This query searches for documents where the fullname
starts with the given value.
A few things to note:
- Firestore queries are case-sensitive, so this matches only when the case also matches exactly. You can emulate lower-case queries, by storing the lower-case version of the
fullname
in a separate file (e.g.fullname_lowercase
) and searching on that. For more on this, see Cloud Firestore Case Insensitive Sorting Using Query and Are Cloud Firestore queries still case sensitive? - This query only searches for documents where the
fullname
starts with the requested value, not where it contains that value in another place. If you want that, consider using a dedicated search engine.
How can we search through 5,000 users in Firestore db?
Integrate a full text search engine, and keep it in sync with Firestore. Nontrivial to implement. Official docs recommend Algolia: https://firebase.google.com/docs/firestore/solutions/search
Related Topics
Take Screenshot of Host App Using iOS Share/Action Extensions
Querying in Firebase by Child of Child
Swift: Google Maps Draw Waypoint Polyline
Swift:Difference in '!' and '' in Swift
Get the String Up to a Specific Character
[_Nscftimer Copywithzone:]: Unrecognized Selector Sent to Instance
Swift: How to Create a Predicate with an Int Value
How to Add Documentation to Enum Associated Values in Swift
No Designated Init for Skshapenode(Circleofradius: Radius)
Table View Cellforrowatindexpath Warning
"Message from Debugger: Unable to Attach" When Running Tests on Osx App
What's the Rationale of Swift's Size Methods Taking 'Int'S
Swift: Oslog/Os_Log Not Showing Up in Console App
Swift 3 Warning: Non-Optional Expression of Type 'String' Used in a Check for Optionals