Make a User Model using Firebase Model Framework Salada

1amageek
3 min readOct 9, 2017

--

I will introduce the User Model that I usually adopt in the application.

What this article will introduce

  • Install Salada
  • Make User Model with Firebase
  • Link Firebase Auth and User Model

Install Salada

$ gem install cocoapods — pre

Cocoapods version 1.4 or higher is required.

pod 'Salada'

Installation is complete!

Make User Model with Firebase

Let’s make a User Model quickly. Even User.swift is OK, but since I did not like conflicting names when creating the same User Model with Realm I have been using Firebase + User.swift since then. Since Firebase Auth also has a class defined as User, I think that it would be better to give some namespace.

This time I will introduce the configuration which is simple but is likely to be used well.

import Firebase

extension Firebase {
class User: Object {

@objc dynamic var name: String?

@objc dynamic var thumbnailImage: File?

let followers: Follower = []

let friends: Friend = []
}
}

Provide user name and thumbnail and follow function.
With File you can work seamlessly with FirebaseStorage.

extension Firebase.User {

static func current(_ completionHandler: @escaping ((Firebase.User?) -> Void)) {
guard let user: User = Auth.auth().currentUser else {
completionHandler(nil)
return
}
Firebase.User.observeSingle(user.uid, eventType: .value, block: { (user) in
guard let user: Firebase.User = user else {
_ = try? Auth.auth().signOut()
completionHandler(nil)
return
}
completionHandler(user)
})
}

public func follow() {
Firebase.User.current { (me) in
guard let me = me else { return }
self.followers.insert(me)
me.friends.insert(self)
}
}

public func unfollow() {
Firebase.User.current { (me) in
guard let me = me else { return }
self.followers.remove(me)
me.friends.remove(self)
}
}
}

You can easily make references by inheriting the Relation class.

extension Firebase {
class Follower: Relation<Firebase.User> { }
class Friend: Relation<Firebase.User> { }
}

Save User

let user: Firebase.User = Firebase.User()
user.name = "hoge"
user.thumbnailImage = File(data: UIImageJPEGRepresentation(image, 1))
user.save()

Get the current user

Firebase.User.current { user in
// Do something
}

Get another user

Firebase.User.observeSingle("id", eventType: .value) { (user) in
// Do something
}

Update property

Firebase.User.current { user in
user.name = "Update"
}

Salada does not provide the function of Update.
It monitors the property and is saved in Firebase in real time at the time when the value is set.

Just set a new value. Why does it look like this because Firebase can be used offline.
It is not necessary to handle errors when offline. Firebase does not have the concept of timeout in the first place and no error is returned. If it is offline, it will be temporarily stored locally and will synchronize with the Firebase itself the moment you reconnect to the network.

Link Firebase Auth and User Model

Actually, this is quite troublesome, and Firebase Auth issues Notification called AuthStateDidChange when authentication is completed, but the Notification you actually want is actually better after user creation after authentication is complete.

Auth.auth().signIn(with: credential) { (authUser, error) in
guard let authUser = authUser else {
print(error)
return
}

// Here AuthStateDidChange is called.
Firebase.User.observeSingle(authUser.uid, eventType: .value) { user in
if let user = user {
// Just login
} else {
// Create new user
let newUser: Firebase.User = Firebase.User(id: authUser.uid)!
newUser.name = authUser.displayName
newUser.save { (_, error) in
if let _ = error {
print(error)
return
}
// Let's call our own Notification here.
}
}
}
}

Please have a nice Firebase Life.

--

--