#はじめに
前回のFirebase/Authenticationを使用してTwitterLoginを実装の続きの記事になります。
今回やること
Twitterログイン成功時に以下二つの実装について説明します。
Storageに保存
・Twitterのアイコン画像をStorageに保存
FireStoreにユーザーデータを保存
・Document名をuidとしDataとしてname,profileImageUrlを持つ
・profileImageUrlにはStorageに保存したアイコン画像のDownLoadURLが入る
Authenticationに登録されているユーザー情報
赤枠で囲われているのがuidになります。
このuidがStorageに保存したファイル名,FireStoreのusersCollection以下のDocument名になります。
前回のTwitterLoginのコードに追加
Pod追加
pod 'Firebase'
pod 'Firebase/Firestore'
pod 'Firebase/Storage'
FireStore,FireStorageを新しくimport
import FirebaseFirestore
import FirebaseStorage
var name: String? //Session情報からログインしたユーザー情報を取得で使用
var profileImage: UIImage? //Session情報からログインしたユーザー情報を取得で使用
var twitterSession: TWTRSession?
override func viewDidLoad() {
super.viewDidLoad()
let logInButton = TWTRLogInButton(logInCompletion: { session, err in
if let err = err { return }
if let session = session {
let authToken = session.authToken
let authTokenSecret = session.authTokenSecret
self.twitterSession = session
let credential = TwitterAuthProvider.credential(withToken: session.authToken, secret: session.authTokenSecret)
Auth.auth().signInAndRetrieveData(with: credential) { (authResult, err) in
if let err = err { return }
//Session情報からログインしたユーザー情報を取得で使用
self.fetchTwitterUser()
}
}
})
logInButton.center = self.view.center
self.view.addSubview(logInButton)
}
Session情報からログインしたユーザー情報を取得
・userからname,profileImageLargeURLを取得
func fetchTwitterUser() {
guard let twitterSession = twitterSession else { return }
let client = TWTRAPIClient()
client.loadUser(withID: twitterSession.userID, completion: { (user, err) in
if let err = err { return }
guard let user = user else { return }
self.name = user.name
let profileImageLargeURL = user.profileImageLargeURL
guard let url = URL(string: profileImageLargeURL) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
if let err = err { return }
guard let data = data else { return }
self.profileImage = UIImage(data: data)
self.saveUserInfoFirebaseDatabase()
}.resume()
})
}
Storageにアイコン画像を保存
・profileImages/uidにアイコン画像保存用のリファレンスを作成
・作成したリファレンスにアイコン画像をアップロード
・アップロード成功時にStorageを参照しファイルのDownLoadURLを取得
func saveUserInfoFirebaseDatabase() {
guard let uid = Auth.auth().currentUser?.uid,
let name = self.name, let profileImage = profileImage,
let profileImageUploadData = profileImage.jpegData(compressionQuality: 0.3) else { return }
let profileImageRef = Storage.storage().reference().child("profileImages").child(uid)
let uploadTask = profileImageRef.putData(profileImageUploadData, metadata: nil) { (metadata, err) in
guard let metadata = metadata else { return }
profileImageRef.downloadURL { (url, err) in
guard let url = url else { return }
}
}
このタイミングでアプリを実行するとuidで命名したリファレンスにアイコン画像が保存されていることが確認できます。
FireStoreにユーザーデータを保存
func saveUserInfoFirebaseDatabase() {
guard let uid = Auth.auth().currentUser?.uid,
let name = self.name, let profileImage = profileImage,
let profileImageUploadData = profileImage.jpegData(compressionQuality: 0.3) else { return }
let profileImageRef = Storage.storage().reference().child("profileImages").child(uid)
let uploadTask = profileImageRef.putData(profileImageUploadData, metadata: nil) { (metadata, err) in
guard let metadata = metadata else { return }
profileImageRef.downloadURL { (url, err) in
guard let url = url else { return }
//FireStoreにデータ保存用のコード追加
let dictionaryValues = ["name": name,
"profileImageUrl": url.absoluteString] as [String : Any]
let db = Firestore.firestore()
db.collection("users").document(uid).setData(dictionaryValues) { err in
if let err = err { return }
}
}
}
}
このタイミングでアプリを実行するとFireStoreにデータが入っていることが確認できます。
uidでDocumentが作成されDataとしてname,profileImageUrlが入っていることが確認できます。
profileImageUrlにはStorageにアップロードしたアイコン画像のDownLoadURLが入っていることも確認できます。
FireStoreに保存したユーザーデータを取得してプロフィール表示
FireStoreにはusersCollectionにuidでDocumentを作成してありますのでuidを取得してこのuidを元にユーザーデータを取得してあげれば良さそうです!
if let user = Auth.auth().currentUser {
let userRef = Firestore.firestore().collection("users").document(user.uid)
userRef.getDocument(completion: { (document, error) in
if let document = document, document.exists {
let profileImageUrl = document["profileImageUrl"]
let name = document["name"]
let url = URL(string: profileImageUrl as! String)
do {
let data = try Data(contentsOf: url!)
let image = UIImage(data: data)
self.imageView.image = image
self.label.text = name as! String
}catch let err {
//error handle
}
}
})
}