14日目,フォロワーのみタイムラインに表示する
今日はタイムラインにおいて,フォローしているユーザの投稿のみ表示する機能を実装しました.
1.データベースの構造
データベースの構造は以下のようになっています.usersのドキュメントにuser-feedを持たせ,フォローしているユーザをタイムラインに表示できるようにしていきます.
2.firestoreへのアップロード
//MARK: -フォローした後,そのフォローした人の投稿を自分のuser-feedに加える機能
static func updateUserFeedAfterFollowing(user:User){
guard let uid = Auth.auth().currentUser?.uid else {return}
let query = COLLECTION_POSTS.whereField("ownerUid", isEqualTo: user.uid)
query.getDocuments { snapshot, error in
guard let documents = snapshot?.documents else {return}
let docIDs = documents.map({$0.documentID})
docIDs.forEach { id in
COLLECTION_USERS.document(uid).collection("user-feed").document(id).setData([:])
}
}
}
このfunc では,渡されたユーザの投稿のドキュメントID(投稿)を取得した後,そのドキュメントIDを現在のユーザ(uid)のuser-feedに載せていきます.このfunc をfollowする機能のところで呼び出すことによって,フォローしたユーザの投稿情報を現在のユーザにもたせます.
3.タイムラインにおけるフォロしているユーザの投稿のみの取得
//MARK: feedにおける投稿の取得
static func fetchFeedPosts(completion: @escaping([Post])->Void){
guard let uid = Auth.auth().currentUser?.uid else {return}
var posts = [Post]()
COLLECTION_USERS.document(uid).collection("user-feed").getDocuments { snapshot, error in
snapshot?.documents.forEach({ document in
fetchPost(withPostId: document.documentID) { post in
posts.append(post)
completion(posts)
}
})
}
}
ここでは現在のユーザが持っている他人の投稿(user-feed)を返す機能になります.これをタイムラインのコントローラにて呼び出していきます.
フォローしているユーザの投稿のみ表示できるようになりました!
4.フォロー解除した時の処理
fetchFeedPostsを以下のように変更することで実現します.
//MARK: フォローした後,そのフォローした人の投稿を自分のuser-feedに加える機能
static func updateUserFeedAfterFollowing(user:User,didFollow:Bool){
guard let uid = Auth.auth().currentUser?.uid else {return}
let query = COLLECTION_POSTS.whereField("ownerUid", isEqualTo: user.uid)
query.getDocuments { snapshot, error in
guard let documents = snapshot?.documents else {return}
let docIDs = documents.map({$0.documentID})
docIDs.forEach { id in
if didFollow{
COLLECTION_USERS.document(uid).collection("user-feed").document(id).setData([:])
}else{
COLLECTION_USERS.document(uid).collection("user-feed").document(id).delete()
}
}
}
}こ
これをfollow,unfollowするところで呼び出し,followするところでは,Boolにtrueを,unfollowではfalseを渡します.そうすることで上のfuncは機能するようになります.
5.その他
このままだと,フォローしたユーザが新たに投稿した場合,その投稿は表示されないのでその点も変更していく.
まず以下のような機能を作成しました
//MARK: フォローしたユーザが新たに投稿した場合のデータをuser-feedに書き込む機能
private static func updateUserFeedAfterPost(postId:String){
guard let uid = Auth.auth().currentUser?.uid else {return}
COLLECTION_FOLLOWERS.document(uid).collection("user-followers").getDocuments { snapshot, _ in
guard let documents = snapshot?.documents else {return}
documents.forEach { document in
COLLECTION_USERS.document(document.documentID).collection("user-feed").document(postId).setData([:])
}
COLLECTION_USERS.document(uid).collection("user-feed").document(postId).setData([:])
}
}
その後この機能をuploadPostにて呼び出します.
//MARK: 投稿する機能
static func uploadPost(caption:String,image:UIImage,user:User,completion: @escaping(FireStoreCompletion)){
guard let uid = Auth.auth().currentUser?.uid else {return}
ImageUploader.uploadImage(image: image) { imageUrl in
let data = ["caption":caption,
"timestamp":Timestamp(date: Date()),
"likes":0,
"imageUrl":imageUrl,
"ownerUid":uid,
"ownerImageUrl":user.profileImageUrl,
"ownerUsername":user.username] as [String : Any]
let docRef = COLLECTION_POSTS.addDocument(data: data,completion: completion)
self.updateUserFeedAfterPost(postId: docRef.documentID)
}
}
新しいコナンの投稿がドラえもんのタイムラインにも表示することができました.