Firebase Realtime Database is a type of database that is cloud-hosted i.e. it runs on the cloud and it can be accessed from any platform i.e. it can be accessed from Android, iOS and Web at the same time. Firebase is easy to use, can store a ton of data, and you can observe data changes in real-time!
The data stored in the Firebase Realtime Database is JSON structured i.e. the entire database will be a JSON tree with multiple nodes. So, unlike SQL database, we don't have tables or records in the JSON tree.
The data present in the database is very important and you shouldn't give access to everyone to use the data present in your database. So, in order to do so, Firebase Realtime Database has some database configuration rules that can be used to provide different access to different users. Following are the database configuration rules:
{ "rules": { ".read": false, ".write": false } }
{ "rules": { ".read": true, ".write": true } }
{ "rules": { "users": { "$uid": { ".read": "$uid === auth.uid", ".write": "$uid === auth.uid" } } } }
Let's prepare account and create a project.
Open the Firebase Website and sign up for a free account. Then, log into your new account and go to your Firebase Dashboard.
Next, click Add Project. In the dialogs that appear, set a project name.
Finally, click Create Project. Then, in the screen that appears, choose Add Firebase to your iOS app.
Another dialog appears. Choose the following settings:
Finally, click Register App. In the next screen that appears, click the big Download GoogleService-Info.plist button. You’ll now download a .plist file, so save it in a convenient location (like ~/Downloads).
Add the .plist file to your Xcode project. Drag-and-drop the file from Finder into Xcode, and add it to the Project Navigator. When a dialog appears, make sure to tick the checkbox for Copy items if needed, and tick the checkbox next to Target.
Finally, click Continue.
Install Firebase SDK
The easiest way to add third-party libraries to your project is with CocoaPods. CocoaPods is a package manager, and it helps you to manage your libraries, download new versions, and integrate them with Xcode.
Open the Podfile file, and add the following lines:
pod 'Firebase/Core' pod 'Firebase/Auth' pod 'Firebase/Database' pod 'ObjectMapper', '~> 3.4'
Configure Firebase in AppDelegate. Start by making sure the Firebase module is imported.
import Firebase
Use the configure
method in FirebaseApp inside the application:didFinishLaunchingWithOptions
function to configure underlying Firebase services from your .plist file.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { FirebaseApp.configure() return true }
Creating a Connection to Firebase. Following establishes a connection to your Firebase database using the provided path.
let ref = Database.database().reference(withPath: "movies") // or let rootRef = Database.database().reference() let itemsRef = rootRef.child("movies")
In order to work easier with the Firebase paths, and references, you create a Constants.swift file to hard-code the paths for the chat data.
Do this:
Then, add the following Swift code to Constants.swift:
import Firebase struct Constants { struct refs { static let databaseRoot = Database.database().reference() static let databaseMovies = databaseRoot.child("movies") } }
Whenever you now need access to the reference for chat data, you can use:
Constants.refs.databaseMovies
Create model.
import Foundation import ObjectMapper import FirebaseDatabase class Movie: Mappable, CustomStringConvertible { var oid: String? var title: String? var year: Int? public var description: String { return "Movie: oid=\(oid), title=\(title)" } init(oid: String?, title: String?, year: Int?) { self.oid = oid self.title = title self.year = year } func mapping(map: Map) { oid <- map["oid"] title <- map["title"] year <- map["year"] } required init?(map: Map) { } } extension BaseMappable { init?(snapshot: DataSnapshot) { guard let json = snapshot.value as? [String: Any] else { return nil } self.init(JSON: json) } }
Or without ObjectMapper.
import Foundation import Firebase struct Movie { var title: String var year: Int var dictionary: [String: Any] { return [ "title": title, "year": year ] } } extension Movie: DocumentSerializable { init?(dictionary: [String : Any]) { guard let owner = dictionary["owner"] as? String, let place = dictionary["place"] as? String, let time = dictionary["time"] as? Date, let title = dictionary["title"] as? String else { return nil } self.init(owner: owner, place: place, time: time, title: title) } }
Save object. Use setValue(_:)
to save data to the database. This method expects a Dictionary
.
let rootRef = Database.database().reference() let itemsRef = rootRef.child("movies") func create() { let oid = itemsRef.childByAutoId().key! let movie = Movie( oid: oid, title: "Movie 1", year: 2009) itemsRef.child(oid).setValue(movie.toJSON()) }
You can update data using updateChildValues(_:)
which passes a dictionary, to update Firebase. This method is different than setValue(_:)
because it only applies updates, whereas setValue(_:)
is destructive and replaces the entire value at that reference.
itemsRef.updateChildValues([ "year": 2010 ])
Retrieving Data. One of the great things Firebase can do is push real-time data to your app, with very little effort or code. It’s literally real-time: you change your data in Firebase, and your UI or data on your iPhone changes. You retrieve data in Firebase by attaching an asynchronous listener to a reference using observe(_:with:)
. This method takes two parameters: an instance of DataEventType
and a closure.
The event type specifies what event you want to listen for. The code listens for a .value
event type, which in turn listens for all types of changes to the data in your Firebase database — add, removed, and changed.
func load() { itemsRef.observe(.value, with: { snapshot in var items: [Movie] = [] for child in snapshot.children { if let snapshot = child as? DataSnapshot, let item = Movie(snapshot: snapshot) { items.append(item) } } print(items) }) }
Sorting. To order the data by the year value you call queryOrdered(byChild:) on the Firebase reference, which takes a key to order by.
ref.queryOrdered(byChild: "year").observe(.value, with: { snapshot in ... })
Useful links