无法追加检索到的文件

时间:2019-11-17 06:30:27

标签: ios swift firebase google-cloud-firestore

我无法将在基于Swift IOS的​​聊天应用程序中从Firestore数据库中检索到的文档追加到“ messages”变量中,在追加后,如代码中所示配置了表格单元格,出现以下错误 错误

Cannot convert value of type '[QueryDocumentSnapshot]' to expected argument type 'DocumentSnapshot'

代码

    var messages: [DocumentSnapshot]! = []
          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
                    }

//here is the error
          self.messages.append(documents)

        }


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 = 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
  }

3 个答案:

答案 0 :(得分:0)

self.messages.append(documents)替换为self.messages.append(contentsOf: documents)

第一种方法采用单个元素,第二种方法采用您所用的集合。 https://developer.apple.com/documentation/swift/array/3126937-append https://developer.apple.com/documentation/swift/array/3126939-append

答案 1 :(得分:0)

var messages: [[String: Any]] = []

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
    }

    for doc in documents {
        self.messages.append(doc.data())
    }
}

答案 2 :(得分:0)

虽然还有其他两个很好的答案,但两者之间可能会有一些困惑

FIRDocumentSnapshot   (Note: renamed to DocumentSnapshot)

要获取特定文档时返回以下内容:someDoc.getDocument(

FIRQuerySnapshot  (Note: renamed to QuerySnapshot)

当将观察者添加到集合中或正在检索一系列文档时,返回哪个:someCollection.getDocuments,然后QuerySnapshot中的每个文档都是谨慎的FIRQueryDocumentSnapshot(重命名为QueryDocumentSnapshot)。 (例如,遍历QuerySnapshot以获得子QueryDocumentSnapshot)

请注意,如果文档不存在,DocumentSnapshot的data属性可能返回nil,因此可以对它进行.exists测试。而QueryDocumentSnapshot永远不会为零(始终存在,因为没有返回删除的数据)。

在问题中,观察者被添加到具有以下内容的集合中

.collection("messages").addSnapshotListener

因此,返回的数据是QuerySnapshot并将其存储为var,则需要匹配var类型

var messagesQuerySnapshot: QuerySnapshot!

然后在侦听器中

db.collection("messages")...addSnapshotListener { querySnapshot, error in
   messagesQuerySnapshot = querySnapshot

但是,我不建议这样做。

我建议使用可以从Firestore检索的数据进行初始化并将其存储在数组中的消息类。

class MessagesClass {
   var msg_id = ""
   var msg = ""
   var from = ""

   convenience init(withQueryDocSnapshot: QueryDocumentSnapshot) {
      //init vars from the document snapshot
   }
}

然后是一个var类数据源数组来保存它们

var messagesArray = [MessageClass]()

然后编写代码以读取消息,创建消息对象并将其添加到dataSource数组

db.collection("messages")...getDocuments { querySnapshot, error in
   guard let snapshot = querySnapshot else {
      print("Error fetching snapshots: \(error!)")
      return
   }

   for doc in snapshot.documents {
      let aMsg = MessageClass(withQueryDocSnapshot: doc)
      self.messagesArray.append(aMsg)
   }
}

注意:我们不在这里添加侦听器,而是一次获取文档。如果要添加侦听器以监视正在添加,更改或删除的用户,则需要其他代码来检测更改。

请参阅Viewing Changes Between Snapshots上的Firebase文档