gpt4 book ai didi

ios - 从 Firestore 数据库检索数据时出现与索引相关的错误

转载 作者:行者123 更新时间:2023-11-28 13:22:25 28 4
gpt4 key购买 nike

我无法使用 Firestore 数据库在 Swift IOS 的聊天应用程序中加载文档,尽管能够成功地从 Firestore 数据库检索数据,但我也添加了 deinit 方法请进一步协助解决错误,我已经添加了完整的 View Controller ,请帮助我错误

'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (47) must be equal to the number of rows contained in that section before the update (23), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

代码

let kBannerAdUnitID = "ca-app-pub-3940256099942544/2934735716"

@objc(FCViewController)
class FCViewController: UIViewController, UITableViewDataSource, UITableViewDelegate,
UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

// Instance variables
@IBOutlet weak var textField: UITextField!
@IBOutlet weak var sendButton: UIButton!
var ref : CollectionReference!
var ref2: DocumentReference!
var messages: [DocumentSnapshot]! = []

var msglength: NSNumber = 10
fileprivate var _refHandle: CollectionReference!

var storageRef: StorageReference!
var remoteConfig: RemoteConfig!

private let db = Firestore.firestore()
private var reference: CollectionReference?
private let storage = Storage.storage().reference()

// private var messages = [Constants.MessageFields]()
//snapshot private var messages: [Constants.MessageFields] = []

private var messageListener: ListenerRegistration?

// var db:Firestore!
@IBOutlet weak var banner: GADBannerView!
@IBOutlet weak var clientTable: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

self.clientTable.register(UITableViewCell.self, forCellReuseIdentifier: "tableViewCell")
// clientTable.delegate = self
//clientTable.dataSource = self



//db = Firestore.firestore()
ref = db.collection("messages").document("hello").collection("newmessages").document("2").collection("hellos").document("K").collection("messages")


ref2 = db.collection("messages").document("hello").collection("newmessages").document("2").collection("hellos").document("K").collection("messages").document()
configureDatabase()
configureStorage()
configureRemoteConfig()
fetchConfig()
loadAd()
}


deinit {
if let refhandle = _refHandle {
let listener = ref.addSnapshotListener { querySnapshot, error in

}

listener.remove()
}
}

func configureDatabase() {

db.collection("messages").document("hello").collection("newmessages").document("2").collection("hellos").document("K").collection("messages").addSnapshotListener { querySnapshot, error in
guard let documents = querySnapshot?.documents else {
print("Error fetching documents: \(error!)")
return
}

/* let name = documents.map { $0["name"]!}
let text = documents.map { $0["text"]!}
let photourl = documents.map { $0["photoUrl"]!}

print(name)

print(text)
print(photourl)*/
self.messages.append(contentsOf: documents)





// self.clientTable.insertRows(at: [IndexPath(row: self.messages.count-1, section: 0)], with: .automatic)

//self.clientTable.reloadData()

}


}



func configureStorage() {
storageRef = Storage.storage().reference()
}

func configureRemoteConfig() {
remoteConfig = RemoteConfig.remoteConfig()
let remoteConfigSettings = RemoteConfigSettings(developerModeEnabled: true)
remoteConfig.configSettings = remoteConfigSettings
}

func fetchConfig() {
var expirationDuration: Double = 3600
// If in developer mode cacheExpiration is set to 0 so each fetch will retrieve values from
// the server.
if self.remoteConfig.configSettings.isDeveloperModeEnabled {
expirationDuration = 0
}
remoteConfig.fetch(withExpirationDuration: expirationDuration) { [weak self] (status, error) in
if status == .success {
print("Config fetched!")
guard let strongSelf = self else { return }
strongSelf.remoteConfig.activateFetched()
let friendlyMsgLength = strongSelf.remoteConfig["friendly_msg_length"]
if friendlyMsgLength.source != .static {
strongSelf.msglength = friendlyMsgLength.numberValue!
print("Friendly msg length config: \(strongSelf.msglength)")
}
} else {
print("Config not fetched")
if let error = error {
print("Error \(error)")
}
}
}
}

@IBAction func didPressFreshConfig(_ sender: AnyObject) {
fetchConfig()
}

@IBAction func didSendMessage(_ sender: UIButton) {
_ = textFieldShouldReturn(textField)
}

@IBAction func didPressCrash(_ sender: AnyObject) {
print("Crash button pressed!")
Crashlytics.sharedInstance().crash()
}

func inviteFinished(withInvitations invitationIds: [String], error: Error?) {
if let error = error {
print("Failed: \(error.localizedDescription)")
} else {
print("Invitations sent")
}
}

func loadAd() {
self.banner.adUnitID = kBannerAdUnitID
self.banner.rootViewController = self
self.banner.load(GADRequest())
}


// UITableViewDataSource protocol methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return messages.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
let cell = self.clientTable .dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath)
// Unpack message from Firebase DataSnapshot
let messageSnapshot: DocumentSnapshot! = self.messages[indexPath.row]
guard let message = messageSnapshot as? [String:String] else { return cell }
let name = message[Constants.MessageFields.name] ?? ""
if let imageURL = message[Constants.MessageFields.imageURL] {
if imageURL.hasPrefix("gs://") {
Storage.storage().reference(forURL: imageURL).getData(maxSize: INT64_MAX) {(data, error) in
if let error = error {
print("Error downloading: \(error)")
return
}
DispatchQueue.main.async {
cell.imageView?.image = UIImage.init(data: data!)
cell.setNeedsLayout()
}
}
} else if let URL = URL(string: imageURL), let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage.init(data: data)
}
cell.textLabel?.text = "sent by: \(name)"
} else {
let text = message[Constants.MessageFields.text] ?? ""
cell.textLabel?.text = name + ": " + text
cell.imageView?.image = UIImage(named: "ic_account_circle")
if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
let data = try? Data(contentsOf: URL) {
cell.imageView?.image = UIImage(data: data)
}
}
return cell
}

func textFieldShouldReturn(_ textField: UITextField) -> Bool {
guard let text = textField.text else { return true }
textField.text = ""
view.endEditing(true)
let data = [Constants.MessageFields.text: text]
sendMessage(withData: data)
return true
}

func sendMessage(withData data: [String: String]) {
var mdata = data
mdata[Constants.MessageFields.name] = Auth.auth().currentUser?.displayName
if let photoURL = Auth.auth().currentUser?.photoURL {
mdata[Constants.MessageFields.photoURL] = photoURL.absoluteString
}

// Push data to Firebase Database
self.ref.document().setData(mdata, merge: true) { (err) in
if let err = err {
print(err.localizedDescription)
}
print("Successfully set newest city data")
}

}

// MARK: - Image Picker

@IBAction func didTapAddPhoto(_ sender: AnyObject) {
let picker = UIImagePickerController()
picker.delegate = self
if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
picker.sourceType = .camera
} else {
picker.sourceType = .photoLibrary
}

present(picker, animated: true, completion:nil)
}

func imagePickerController(_ picker: UIImagePickerController,
didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
picker.dismiss(animated: true, completion:nil)
guard let uid = Auth.auth().currentUser?.uid else { return }

// if it's a photo from the library, not an image from the camera
if #available(iOS 8.0, *), let referenceURL = info[.originalImage] as? URL {
let assets = PHAsset.fetchAssets(withALAssetURLs: [referenceURL], options: nil)
let asset = assets.firstObject
asset?.requestContentEditingInput(with: nil, completionHandler: { [weak self] (contentEditingInput, info) in
let imageFile = contentEditingInput?.fullSizeImageURL
let filePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000))/\((referenceURL as AnyObject).lastPathComponent!)"
guard let strongSelf = self else { return }
strongSelf.storageRef.child(filePath)
.putFile(from: imageFile!, metadata: nil) { (metadata, error) in
if let error = error {
let nsError = error as NSError
print("Error uploading: \(nsError.localizedDescription)")
return
}
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
})
} else {
guard let image = info[.originalImage] as? UIImage else { return }
let imageData = image.jpegData(compressionQuality:0.8)
let imagePath = "\(uid)/\(Int(Date.timeIntervalSinceReferenceDate * 1000)).jpg"
let metadata = StorageMetadata()
metadata.contentType = "image/jpeg"
self.storageRef.child(imagePath)
.putData(imageData!, metadata: metadata) { [weak self] (metadata, error) in
if let error = error {
print("Error uploading: \(error)")
return
}
guard let strongSelf = self else { return }
strongSelf.sendMessage(withData: [Constants.MessageFields.imageURL: strongSelf.storageRef.child((metadata?.path)!).description])
}
}
}

func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion:nil)
}

@IBAction func signOut(_ sender: UIButton) {
let firebaseAuth = Auth.auth()
do {
try firebaseAuth.signOut()
dismiss(animated: true, completion: nil)
} catch let signOutError as NSError {
print ("Error signing out: \(signOutError.localizedDescription)")
}
}

func showAlert(withTitle title: String, message: String) {
DispatchQueue.main.async {
let alert = UIAlertController(title: title,
message: message, preferredStyle: .alert)
let dismissAction = UIAlertAction(title: "Dismiss", style: .destructive, handler: nil)
alert.addAction(dismissAction)
self.present(alert, animated: true, completion: nil)
}
}

}

最佳答案

Edit

在主线程上执行这段代码

for doc in documents {
self.messages.append(doc)
self.clientTable.insertRows(at: [IndexPath(row: self.messages.count-1, section: 0)], with: .automatic)
}

这应该有效..

关于ios - 从 Firestore 数据库检索数据时出现与索引相关的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58898685/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com