【发布时间】:2019-09-29 03:41:21
【问题描述】:
我在将使用 Firebase 实时数据库的 getPhotos 方法迁移到使用 Firestore 的 getPhotos1 时遇到问题,但由于某种原因无法将 getPhotos1 中的文档快照获取到 Photos1 对象。
这是我使用 Firebase 实时数据库的 getPhotos 方法:
static func getPhotos (completion: @escaping ([Photo]) -> Void) {
//Getting a reference to the database
let dbRef = Database.database().reference()
//Make the db call
dbRef.child("photos").observeSingleEvent(of: .value) { (snapshot) in
//Declare an array to hold the photos
var retrievedPhotos = [Photo]()
//Get the list of snapshots
let snapshots = snapshot.children.allObjects as? [DataSnapshot]
if let snapshots = snapshots {
//Loop through each snapshot and parse out the photos
for snap in snapshots {
//Try to create a photo from a snapshot
let p = Photo(snapshot: snap)
//If successful, then add it to our array
if p != nil {
retrievedPhotos.insert(p!, at: 0)
}
}
}
//After parsing the snapshots, call the completion closure
completion(retrievedPhotos)
}
}
这是它的对象
import Foundation
import RealmSwift
import FirebaseDatabase
import Firebase
class Photo: Object {
@objc dynamic var photoId:String?
@objc dynamic var byId:String?
@objc dynamic var byUsername:String?
@objc dynamic var date:String?
@objc dynamic var url:String?
@objc dynamic var postId:String?
override static func primaryKey() -> String? {
return "photoId"
}
override static func indexedProperties() -> [String] {
return ["byUsername"]
}
convenience init?(snapshot:DataSnapshot){
self.init ()
//Photo data
let photoData = snapshot.value as? [String:String]
if let photoData = photoData {
let photoId = snapshot.key
let byId = photoData["byId"]
let byUsername = photoData["byUsername"]
let date = photoData["date"]
let url = photoData["url"]
let postId = photoData["postId"]
guard byId != nil && byUsername != nil && date != nil && url != nil && postId != nil else {
return nil
}
self.photoId = photoId
self.byId = byId
self.byUsername = byUsername
self.date = date
self.url = url
self.postId = postId
}
}
}
这是我使用 Firestore 的 getPhotos1 方法,不起作用:
static func getPhotos1 (completion: @escaping ([Photo1]) -> Void) {
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("posts").getDocuments() {snapshot, error in
//Declare an array to hold the photos
var retrievedPhotos = [Photo1]()
if error == nil && snapshot != nil {
for document in snapshot!.documents {
let p = Photo1(snapshot: document)
print(p!)
if p != nil {
retrievedPhotos.insert(p!, at: 0)
//print("retrievedPhotos: \(retrievedPhotos)")
}
}
}
//After parsing the snapshots, call the completion closure
completion(retrievedPhotos)
}
}
这就是它的对象
class Photo1: Object {
@objc dynamic var photoId:String?
@objc dynamic var byId:String?
@objc dynamic var byUsername:String?
@objc dynamic var date:String?
@objc dynamic var url:String?
@objc dynamic var postId:String?
override static func primaryKey() -> String? {
return "photoId"
}
override static func indexedProperties() -> [String] {
return ["byUsername"]
}
convenience init?(snapshot:DocumentSnapshot){
self.init ()
//Photo data
let photoData = snapshot.data() as? [String:String]
if let photoData = photoData {
let photoId = snapshot.documentID
let byId = photoData["byId"]
let byUsername = photoData["byUsername"]
let date = photoData["date"]
let url = photoData["url"]
let postId = photoData["postId"]
guard byId != nil && byUsername != nil && date != nil && url != nil && postId != nil else {
return nil
}
self.photoId = photoId
self.byId = byId
self.byUsername = byUsername
self.date = date
self.url = url
self.postId = postId
}
}
}
10 月 1 日编辑: 更新了 getPhoto1 方法。
static func getPhotos1 (completion: @escaping ([Photo1]) -> Void) {
//Get a Firebase reference
let db = Firestore.firestore()
db.collection("posts").getDocuments() { (snapshot, error) in
//Declare an array to hold the photos
var retrievedPhotos = [Photo1]()
print("This is snapshot: \(String(describing: snapshot))")
if error == nil && snapshot != nil {
for document in snapshot!.documents {
let documentData = document.data()
print("This is DocData: \(documentData)")
let p = Photo1(snapshot: documentData)
print("This is p: \(p)")
if p != nil {
retrievedPhotos.insert(p!, at: 0)
print("retrievedPhotos: \(retrievedPhotos)")
}}}
//After parsing the snapshots, call the completion closure
completion(retrievedPhotos)
}}
但是我收到了这个错误:
Cannot convert value of type '[String : Any]' to expected argument type 'DocumentSnapshot'
提前感谢您的建议。
我试图搜索以前的帖子,虽然有一些,但我无法弄清楚,因为它们不是 Swift 特定的。
【问题讨论】:
-
这个问题似乎不完整。您的 Firestore 代码中没有任何内容与您的 Firebase 实时数据库代码匹配。您正在读取两个不同的节点名称(照片和帖子),您的 Photo 对象使用 RTDB 代码(例如,没有使用 Firestore 代码的对象),最重要的是,您的 Firestore 代码除了阅读文档之外并没有真正做任何事情在您的帖子集合中。你能解决这个问题并澄清你在问什么吗?
-
在'getPhotos1'方法中删除一些评论//后,我正在尝试做同样的事情,即在p中转换快照文档,这与在'中将snap转换为p相同获取照片'。在照片的对象中,我知道当我开始使用“getPhotos1”方法时,我必须更改一些东西才能使其工作,例如“DataSnapshot”到“DocumentSnapshot”等。我特别需要帮助来获取“getPhotos1”方法像在“getPhotos”中一样,在retrievePhotos 中返回完整的照片数组。现在它返回 nil 或者甚至不会根据我的尝试构建
-
我想你错过了我的意思。您的代码
let p = Photo(snapshot: document)将 Firestore DocumentSnapshot 传递给您的 Photo 对象,该对象需要 Firebase 实时数据库 DataSnapshot 对象,并且两者不兼容。因此,不会创建 Photo 对象,也无法将其添加到数组中。您需要更新您的 Photo 对象以使用 Firestore DocumentSnapshot 对象进行初始化。 -
我为 getPhoto1 更新了 Photo 对象(现在是 Photo1),以确保它使用正确的 Firestore 协议,但 p(在 getPhoto1 方法中)仍然为对象返回 nil
-
接下来是添加错误检查。如果有任何错误,您的代码会继续运行而不通知您。
标签: ios swift firebase google-cloud-firestore