• Implement firebase in the app
• Create a firebase project
Firecore authentification
• Setup (Required)
• Create a new user (Sign Up)
• Log in an existing user
• Get the currently signed-in user
• Get user information
• Log out an existing user
• Set a user's password
• Send a password reset email
• Delete a user
Email and password validation
• Password validation
• Password validation with live feedback
• Email validation
Firebase Database
Database | Read Data
• Read all documents in a collection
• Read multiple documents
• Read all fields of a specific document
• Read a specific field
• Read a specific field (live update)
Database | Update Data
• Update a document
• Update a field of a document
• Update elements of an array
• Update only one element of an array
Database | Add Data
• Add a collection
• Add a document (specified ID)
• Add a document (auto generated ID)
• Add a field data to a document
• Add elements to an array
Database | Delete Data
• Delete document
• Delete field
• Delete collection
• Delete elements from an array
Others
• Operators
• Compound queries
• Sort and limit data
• Order by multiple fields
• Use ID document
• Server Timestamp
• Increment a numeric value
Rules
• Basics
• Advanced
FIRECORE AUTHENTIICATION
Setup (required)
import Firebase
class VC_ViewController: UIViewController {
FirebaseApp.configure()
if Auth.auth().currentUser != nil {
// User is signed in.
// ...
} else {
// No user is signed in.
// ...
}
Get user information
if let user = user {
let uid = user.uid
let email = user.email
let photoURL = user.photoURL
var multiFactorString = "MultiFactor: "
for info in user.multiFactor.enrolledFactors {
multiFactorString += info.displayName ?? "[DispayName]"
multiFactorString += " "
}
// ...
}
Log out existing user
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
} catch let signOutError as NSError {
print("Error signing out: %@", signOutError)
}
Alternative:
do { try Auth.auth().signOut()
} catch let signOutError as NSError {
print("Error signing out: %@", signOutError)
}
Set a user's password
Auth.auth().currentUser?.updatePassword(to: password) { error in
// ...
}
Send a password reset email
Auth.auth().sendPasswordReset(withEmail: email) { error in
// ...
}
Delete a user
let user = Auth.auth().currentUser
user?.delete { error in
if let error = error {
// An error happened.
} else {
// Account deleted.
}
}
@objc func PswdDidChange(_ textField: UITextField) {
var pswdError = ""
let lenghtPswd = pswdTextfield.text!.count
if isValidPassword(strToValidate: pswdTextfield.text!) {
pswdError = ""
} else if (lenghtPswd > 0){
pswdError = "Password must contain at least 8 characters, \n 1 capital letter, 1 digit and 1 special character"
}
PswdErrorInitial = ""
PswdErrorReason = ""
var SecondError = false
let EightChars = ".{8,}"
let OneUpperCase = ".*[A-Z]+.*"
let OneLowerCase = ".*[a-z]+.*"
let OneDigit = ".*[0-9]+.*"
let OneSpecial = ".*[\\.#?!@$%^&*-]+.*"
if !NSPredicate(format: "SELF MATCHES %@", EightChars).evaluate(with: strToValidate){
PswdErrorReason = PswdErrorReason + "8 chars"
PswdErrorInitial = "Password must contain at least "
SecondError = true
}
if !NSPredicate(format: "SELF MATCHES %@", OneDigit).evaluate(with: strToValidate){
if SecondError { PswdErrorReason = PswdErrorReason + ", "}
PswdErrorReason = PswdErrorReason + "1 digit"
PswdErrorInitial = "Password must contain at least "
}
if !NSPredicate(format: "SELF MATCHES %@", OneUpperCase).evaluate(with: strToValidate){
if SecondError { PswdErrorReason = PswdErrorReason + ", "}
PswdErrorReason = PswdErrorReason + "1 capital letter"
PswdErrorInitial = "Password must contain at least "
}
if !NSPredicate(format: "SELF MATCHES %@", OneLowerCase).evaluate(with: strToValidate){
if SecondError { PswdErrorReason = PswdErrorReason + ", "}
PswdErrorReason = PswdErrorReason + "1 small letter"
PswdErrorInitial = "Password must contain at least "
}
if !NSPredicate(format: "SELF MATCHES %@", OneSpecial).evaluate(with: strToValidate){
if SecondError { PswdErrorReason = PswdErrorReason + ", "}
PswdErrorReason = PswdErrorReason + "1 special character"
PswdErrorInitial = "Password must contain at least "
}
let pswdValidationRegex = "^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\.#?!@$%^&*-]).{8,}$"
let pswdValidationPredicate = NSPredicate(format: "SELF MATCHES %@", pswdValidationRegex)
docRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
B. Read multiple documents in a collection
let docRef = db.collection("cities").whereField("capital", isEqualTo: true)
docRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
}
}
}
C. Read all fields of a specific document
let docRef = db.collection("cities").document("SF")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let data = document.data()
if let data = data {
print("data", data)
self.city = data["state"] as? String ?? ""
}
} else {
print("Document does not exist")
}
}
D. Read a specific field of a specific document in a collection
let docRef = db.collection("cities").document("SF")
docRef.getDocument { (document, error) in
if let document = document, document.exists {
let field = document.get('fieldname')
} else {
print("Document does not exist")
}
}
E. Read a specific field of a specific document with live update
let docRef = db.collection("cities").document("SF")
docRef.addSnapshotListener { (document, error) in
if let document = document, document.exists {
let field = document.get('fieldname')
} else {
print("Document does not exist")
}
}
FIREBASE DATABASE | Update Data
A. Update a document (delete and overwrite the whole document)
db.collection("cities").document("LA").setData([
"name": "Los Angeles",
"state": "CA",
"country": "USA"
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document successfully written!")
}
}
B. Update a field of a document with setData() (merge: true)
// Update fields in the document (add the data if not existing)
// Recommended if you're not sure whether the document exists (to avoid overwriting)
db.collection("cities").document("BJ").setData([ "capital": true ], merge: true)
C. Update a field of a document with updateData()
// Update fields but will fail if the document doesn't exist
db.collection("cities").document("BJ").updateData([ "capital": false ])
D. Update elements of an array
// Replaces the entire array with an array containing the updated data
let docRef = db.collection("cities").document("DC")
docRef.updateData([
"regions": ["greater_virginia"])
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document updated")
}
}
E. Update only one element of an array
TO COMPLETE !!!!
FIREBASE DATABASE | Add Data
A. Add a collection
db.collection("cities").document("New York").setData([
"people": 10000000,
"country": "USA",
]) { err in
if let err = err {
print("Error writing document: \(err)")
} else {
print("Document added")
}
}
}
let newCityRef = db.collection("cities").document()
// later...
newCityRef.setData([
// ...
])
F. Server Timestamp
db.collection("objects").document("some-id").updateData([
"lastUpdated": FieldValue.serverTimestamp(),
]) { err in
if let err = err {
print("Error updating document: \(err)")
} else {
print("Document successfully updated")
}
}
G. Increment a numeric value
let docRef = db.collection("cities").document("DC")
// Automically increment the population of the city by 50.
// Note that increment() with no arguments increments by 1.
docRef.updateData([
"population": FieldValue.increment(Int64(50))
])
RULES
Read and write rules
• A read rule can be broken into get and list
• A write rule can be broken into create, update, and delete
Basic structure of the rules framework
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /Games/{document=**} {
allow read: if request.auth != null;
allow write: if false;
allow create: if false;
allow update: if request.auth.token.email == uid && UserAllFieldsPermission(request);
allow delete: if false;
}
}
}
For a specific document in a collection
match /Users/{uid} {
...
}
For any document in a collection
match /Games/{document=**} {
...
}
Forbidden for anyone
allow read, write: if false;
Allowed for anyone authentified
allow read, write: if request.auth != null;
Allowed for a given email address
allow read, write: if request.auth.token.email == uid;