Swift
Firebase
Firestore

TwitterLogin成功時にユーザー情報を取得しFireStoreに保存する方法


はじめに

前回のFirebase/Authenticationを使用してTwitterLoginを実装の続きの記事になります。


今回やること

Twitterログイン成功時に以下二つの実装について説明します。

Storageに保存

・Twitterのアイコン画像をStorageに保存

FireStoreにユーザーデータを保存

・Document名をuidとしDataとしてname,profileImageUrlを持つ

・profileImageUrlにはStorageに保存したアイコン画像のDownLoadURLが入る


Authenticationに登録されているユーザー情報

赤枠で囲われているのがuidになります。

このuidがStorageに保存したファイル名,FireStoreのusersCollection以下のDocument名になります。

スクリーンショット_2018-10-13_3_04_21(2).png


前回の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で命名したリファレンスにアイコン画像が保存されていることが確認できます。

スクリーンショット_2018-10-13_3_05_10(2).png


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が入っていることも確認できます。

tmp.png


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
}
}
})
}

こんな感じで画像と名前が表示できました!!(雑なUIですいませんmm)

IMG_9415.PNG