Showing post data from logged in user only swift/xcode/firebase

混江龙づ霸主 提交于 2020-06-17 02:53:25

问题


Hey I have been following tutorials online to try and make a social media app and it works fine where all the posts made by users populates in one scene but in another scene I would like for the users who are currently logged in to be able to see their posts only instead of having to find their posts from a bunch of posts made by other users, below are my code samples:

Posts Code:

import Foundation
import UIKit
import Firebase


class Posts{

var id: String
var author: UserProfile
var text: String
var timestamp:Double
var createdAt:Date


init(id:String, author:UserProfile,text:String,timestamp:Double) {
    self.id = id
    self.author = author
    self.text = text
    self.timestamp = timestamp
    self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
}


static func parse(_ key:String, _ data:[String:Any]) -> Posts? {

    if let author = data["author"] as? [String:Any],
        let uid = author["uid"] as? String,
        let name = author["name"] as? String,
        let photoURL = author["photoURL"] as? String,
        let url = URL(string:photoURL),
        let text = data["text"] as? String,
        let timestamp = data["timestamp"] as? Double {

        let userProfile = UserProfile(uid: uid, name: name, photoURL: url)
        return Posts(id: key, author: userProfile, text: text, timestamp:timestamp)


        func performDeepQuery() {
             guard let user = Auth.auth().currentUser else { return }
            let uid = user.uid
            let ref = Database.database().reference().child("posts")
            let query = ref.queryOrdered(byChild: "author/uid").queryEqual(toValue: uid)
            query.observeSingleEvent(of: .value, with: { snapshot in
                let allPosts = snapshot.children.allObjects as! [DataSnapshot]
                for postSnap in allPosts {

                    let text = postSnap.childSnapshot(forPath: "text").value as? String ?? "No Text"
                    print(text)
                   //same as above
                }
            })
        }



  }

  return nil }
 }

func numberOfSections(in tableView: UITableView) -> Int {
     return 2

 }

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     switch section {
            case 0:
                return theposts.count
            case 1:
                return fetchingMore ? 1 : 0
            default:
                return 0
            }    }


 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.section == 0 { let cell = HomeViewControllerScene.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! Posting_TableViewCell
     cell.set(theposts: theposts[indexPath.row])
     return cell}
 else {
         let cell = HomeViewControllerScene.dequeueReusableCell(withIdentifier: "loadingCell", for: indexPath) as! LoadingCell
         cell.spinner.startAnimating()
         return cell
     }
 }


 func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {


     cellHeights[indexPath] = cell.frame.size.height
 }


 func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return cellHeights[indexPath] ?? 72.0
    }

Please someone help me out here I have been scratching my head for a while with this!!!


回答1:


I believe the question is how to get the posts for a certain user. The structure looks good but no need to have a child node 'author' in each post so instead of this:

posts
   post_id_0
      author
         author data
      text: "Hello, World"
      uid: "uid_0"

do this

posts
   post_id_0
      text: "Hello, World"
      uid: "uid_0"
      name: "usmaan"
      photoURL:"https://firebasestorage..."

So now just query for this users posts (this is for Firestore, scroll down fo the RTDB solution)...

func getThisUsersPosts() {
    let uid = "uid_0" //this users uid
    self.db.collection("posts]").whereField("uid", isEqualTo: uid).getDocuments { (snapshot, error) in
        if let err = error {
            print(err.localizedDescription)
            return
        }

        if let doc = snapshot?.documents {
            for d in doc {
                let text = d.get("text") as? String ?? "No Post Text"
                print(text)
            }
        } else {
            print("no posts found")
        }
    }
}

self.db points to my Firestore.

EDIT:

OP is using the Real Time Database so here's the code for that

func getThisUsersPosts() {
    let uid = "uid_0"
    let ref = self.ref.child("posts") //self.ref points to MY firebase.
    let query = ref.queryOrdered(byChild: "uid").queryEqual(toValue: uid)
    query.observeSingleEvent(of: .value, with: { snapshot in
        let allPosts = snapshot.children.allObjects as! [DataSnapshot]
        for postSnap in allPosts {
            let text = postSnap.childSnapshot(forPath: "text").value as? String ?? "No Text"
            print(text)
        }
    })
}

EDIT 2:

OP wants to keep their same structure.

To query for data that's two levels deep we use what's called Deep Query and will look something like this:

func performDeepQuery() {
    let uid = "uid_0"
    let ref = self.ref.child("posts")
    let query = ref.queryOrdered(byChild: "author/uid").queryEqual(toValue: uid)
    query.observeSingleEvent(of: .value, with: { snapshot in
        let allPosts = snapshot.children.allObjects as! [DataSnapshot]
        for postSnap in allPosts {
           //populate your tableView datasource here
           let post = PostClass()
           post.postId = postSnap.key
           post.name = postStap.childSnapshot("name").value as? String ?? "No Post Name"
           post.text = postStap.childSnapshot("text").value as? String ?? "No Post Text"
           self.postArray.append(post)
        }
        self.myTableView.reloadData()
    })
}

which will perform a deep query on this structure

posts
   post_0
      author
         uid: "uid_0"
      name: "post 0 name"
      text: "post 0 text"

The PostClass could be this

class PostClass {
   var postId = ""
   var name = ""
   var text = ""
}

More Info:

To get the current users uid (which is covered in the getting started guide as well) and assuming you are authenticated (otherwise it will be nil)

guard let user = Auth.auth().currentUser else { return }
let uid = user.uid


来源:https://stackoverflow.com/questions/62046489/showing-post-data-from-logged-in-user-only-swift-xcode-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!