如何在快速点击 Firestore 中的 uitablecellviewcell 时获取文档 ID
Posted
技术标签:
【中文标题】如何在快速点击 Firestore 中的 uitablecellviewcell 时获取文档 ID【英文标题】:how to get document id on tapping the uitablecellviewcell in Firestore in swift 【发布时间】:2019-08-30 08:02:38 【问题描述】:如何在点击 UItableViewCell 时获取文档 ID?
我知道下面的代码确实给了我行索引,但是对于提要帖子,我想每次都获取特定帖子的文档 ID
我曾尝试通过模型文件中的密钥设置来检索文档 ID,但无济于事
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
print("row selected: \(indexPath.row)")
performSegue(withIdentifier: "toDetailView", sender: indexPath)
帖子模型
import Foundation
import Firebase
import FirebaseFirestore
protocol DocumentSerializable
init?(dictionary:[String:Any])
struct Post
var _username: String!
var _postTitle: String!
var _postcategory: String!
var _postContent: String!
var dictionary:[String:Any]
return [
"username": _username,
//"profile_pic":profile_pic,
"postTitle":_postTitle,
"postcategory":_postcategory,
"postContent":_postContent
]
extension Post : DocumentSerializable
init?(dictionary: [String : Any])
guard let username = dictionary["username"] as? String,
// let profile_pic = dictionary["profile_pic"] as? String,
let postTitle = dictionary["postTitle"] as? String,
let postcategory = dictionary["postcategory"] as? String,
let postContent = dictionary["postContent"] as? String else return nil
self.init( _username: username ,_postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
将整个集合检索到的代码。表格视图
import Foundation
import UIKit
import Firebase
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
var tableView:UITableView!
var posts = [Post]()
var db: Firestore!
var postKey:String = ""
private var documents: [DocumentSnapshot] = []
//public var posts: [Post] = []
private var listener : ListenerRegistration!
override func viewDidLoad()
super.viewDidLoad()
db = Firestore.firestore()
self.navigationController?.navigationBar.isTranslucent = false
tableView = UITableView(frame: view.bounds, style: .plain)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
tableView.backgroundColor = UIColor(white: 0.90,alpha:1.0)
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(ios 11.0, *)
layoutGuide = view.safeAreaLayoutGuide
else
// Fallback on earlier versions
layoutGuide = view.layoutMarginsGuide
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
retrieveAllPosts()
//checkForUpdates()
override func didReceiveMemoryWarning()
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
/* override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
performSegueWithIdentifier("toDetailPage", sender: indexPath)
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
let indexPath = self.tableView.indexPathForSelectedRow
let person = personList[indexPath!.row]
if segue.identifier == "toDetailPage"
let DetailBookViewController = (segue.destinationViewController as! DetailPage)
DetailBookViewController.user_name = user_name
DetailBookViewController.user_age = user_age
DetailBookViewController.user_urlPicture = user_urlPicture
*/
@IBAction func handleLogout(_ sender:Any)
try! Auth.auth().signOut()
self.dismiss(animated: false, completion: nil)
/*func checkForUpdates()
db.collection("posts").whereField("timeStamp", isGreaterThan: Date())
.addSnapshotListener
querySnapshot, error in
guard let snapshot = querySnapshot else return
snapshot.documentChanges.forEach
diff in
if diff.type == .added
self.posts.append(Post(dictionary: diff.document.data())!)
DispatchQueue.main.async
self.tableView.reloadData()
*/
func retrieveAllPosts()
let postsRef = Firestore.firestore().collection("posts").limit(to: 50)
postsRef.getDocuments (snapshot, error) in
if let error = error
print(error.localizedDescription)
else
if let snapshot = snapshot
for document in snapshot.documents
let data = document.data()
self.postKey = document.documentID
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post(_postKey:self.postKey, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
self.posts.append(newSourse)
print(self.postKey)
self.tableView.reloadData()
/* postsRef.getDocuments() (querySnapshot, err) in
if let err = err
print("Error getting documents: \(err)")
else
for document in querySnapshot!.documents
print("\(document.documentID) => \(document.data())")
self.posts = querySnapshot!.documents.flatMap(Post(dictionary: $0.data()))
DispatchQueue.main.async
self.tableView.reloadData()
*/
func numberOfSections(in tableView: UITableView) -> Int
return 1
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return posts.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
print("row selected: \(indexPath.row)")
//performSegue(withIdentifier: "toDetailView", sender: indexPath)
【问题讨论】:
我假设数据模型只包含 Firestore 返回的对象?只需将文档的 documentId 添加到您的数据模型类中。您需要添加更多关于如何加载数据的代码。 我已经更新了我的模型类,你能指导我如何在上面的类中添加documentId @inexcitus 只需将string
类型的新属性添加到您的Post
结构。然后在使用 Firestore 加载文档时,使用 DocumentReference 中的 documentId 并将其存储在您的 Post`` 实例中。
我请求您按照您所说的更新上面的代码,因为当它出于相同目的而初始化时,它会显示错误,我尝试了 *** 上可用的各种示例,但它总是显示一个或另一个错误
@inexcitus 请帮忙
【参考方案1】:
将新的 documentId 属性添加到您的 Post
结构:
struct Post
var _username: String!
var _postTitle: String!
var _postcategory: String!
var _postContent: String!
var _documentId: String! // This is new.
var dictionary:[String : Any]
return [
"documentId" : _documentId, // This is new.
"username": _username,
//"profile_pic":profile_pic,
"postTitle":_postTitle,
"postcategory":_postcategory,
"postContent":_postContent
]
extension Post : DocumentSerializable
init?(dictionary: [String : Any])
guard let username = dictionary["username"] as? String,
// let profile_pic = dictionary["profile_pic"] as? String,
let postTitle = dictionary["postTitle"] as? String,
let postcategory = dictionary["postcategory"] as? String,
let documentId = dictionary["documentId"] as? String // This is new.
let postContent = dictionary["postContent"] as? String else return nil
self.init( _username: username ,_postTitle: postTitle, _postcategory: postcategory, _postContent: postContent, _documentId: documentId)
更改您的retrieveAllPosts
函数并设置 Post 实例的 documentId,不要为此使用全局变量:
if let snapshot = snapshot
for document in snapshot.documents
let data = document.data()
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post(_postKey:self.postKey, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent, _documentId: document.documentId)
self.posts.append(newSourse)
现在您可以在 didSelectRowAt 中访问所选 Post
的 documentId:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let post = self.posts[indexPath.row]
Swift.print(post.documentId)
// print("row selected: \(indexPath.row)")
// performSegue(withIdentifier: "toDetailView", sender: indexPath)
希望这将引导您走向正确的方向。
【讨论】:
非常感谢,好几天没用了,现在可以用了.....非常感谢以上是关于如何在快速点击 Firestore 中的 uitablecellviewcell 时获取文档 ID的主要内容,如果未能解决你的问题,请参考以下文章
如何快速解码来自 Firebase Firestore 的时间戳
如何在 Swift 中从 Cloud FireStore Firebase 访问特定字段
Vuejs 和 Firestore - 如何在 Firestore 中的数据更改时进行更新