我在使用Firestore将Firebase Realtime Database的<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://dlang.org/">here</a>.</p>
</body></html>
方法迁移到getPhotos
时遇到问题,但是由于某种原因无法将getPhotos1
中的文档快照迁移到{{1 }}对象。
这是我使用Firebase实时数据库的getPhotos1
方法:
Photos1
这是对象
getPhotos
这是我使用Firestore的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
}
}
}
这是对象
getPhotos1
编辑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]()
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
}
}
}
感谢您的建议。
我尝试在此上搜索以前的线程,尽管有几个线程,但由于它们不是特定于Swift的,所以我无法弄清楚。
答案 0 :(得分:0)
问题中的代码有很多问题;我认为可能会引起某些混乱的三个不同的API(Firebase RealTime数据库,Firestore和Realm)。
让我们直接用Firestore的答案追逐。此代码将读取Firestore集合中的文档,基于该数据创建PhotoClass对象,并将它们存储在数组中。假设结构是这样
photos //a collection
photo_0 //a document
byUserName: "Henry"
byId: "uid_0"
photo_1
byUserName: "George"
byId: "uid_1"
这里是PhotoClass-我默认将属性设置为空字符串而不是nils,以减少处理nil的需要。由于我们没有使用Realm,因此我也删除了Object定义,并将vars更改为Swift vars,而不是Realm(@objc dynamic)所需的ObjC vars
class PhotoClass {
var photoId = ""
var byId = ""
var byUsername = ""
//var date:String?
//var url:String?
//var postId:String?
init(withDocumentSnapshot: DocumentSnapshot) {
self.photoId = withDocumentSnapshot.documentID
self.byUsername = withDocumentSnapshot.get("userName") as? String ?? "No User Name"
self.byId = withDocumentSnapshot.get("byId") as? String ?? "No uid"
}
}
请注意,如果读取属性为nil,我将默认值设置为已知字符串。这样,如果属性丢失或为零,则应用程序不会崩溃。如果要使用nil值,那很酷,但是必须通过在整个过程中安全地使用它们来保护代码。
然后是一个数组,用于存储照片
var photosArray = [PhotoClass]()
然后使用代码读取photos节点内的所有文档,创建PhotoClass对象并填充数组
func readAllPhotos() {
let photosCollection = self.db.collection("photos")
photosCollection.getDocuments(completion: { snapshot, err in
if let err = err {
print(err.localizedDescription)
return
}
for doc in snapshot!.documents {
let photo = PhotoClass(withDocumentSnapshot: doc)
self.photosArray.append(photo)
}
})
}
同样,请注意,有适当的代码可以检查错误并在未找到节点或发生其他错误的情况下保护应用程序。