I get this error when mapping the results of a firebase query into my model.
"Argument passed to call that takes no arguments" exactly in the return conversations point. why??????
I sincerely don't know why, probably something simple, hopefully Peter Friese will see this post...
@Published var chats = [Conversations]()
private let db = Firestore.firestore()
private let user = Auth.auth().currentUser
func getFilteredConversations(query: String) {
if (user != nil) {
db.collection("conversations").whereField("users", arrayContains: user!.displayName).addSnapshotListener { (querySnapshot, error) in
guard let documents = querySnapshot?.documents else {
print("no conversations found")
return
}
//mapping
self.chats = documents.map{(queryDocumentSnapshot) -> Conversations in
let data = queryDocumentSnapshot.data()
let docId = queryDocumentSnapshot.documentID
let users = data["users"] as? [String] ?? [""]
let msgs = data["messages"] as? [Message] ?? []
let unreadmsg = data["hasUnreadMessage"] as? Bool ?? false
//ERROR HERE!!!!! Argument passed to call that takes no arguments
return Conversations(id: docId, users: users, messages: msgs, hasUnreadMessage: unreadmsg)
}
}
}
}
class Conversations: Decodable, Identifiable, ObservableObject {
//var id: UUID { person.id }
var id: String = ""
var users: [String] = [""]
var messages: [Message] = []
var hasUnreadMessage : Bool = false
}
//ERROR here as well saying it's not decodable!
struct Message: Decodable, Identifiable {
enum MessageType {
case Sent, Received
}
let id = UUID()
let date: Date
let text: String
let type: MessageType?
init(_ text: String, type: MessageType, date: Date) {
self.date = date
self.text = text
self.type = type
}
init(_ text: String, type: MessageType) {
self.init(text, type: type, date: Date())
}
}
CodePudding user response:
The problem is that Conversations
is defined as a class
with default values and no initializer. So, the only way to initialize it is to use Conversations()
(thus the no arguments error). Instead, Conversations
should almost certainly be a struct
and not be an ObservableObject
(it doesn't have any @Published
properties anyway and is already getting broadcasted by chats
which is @Published
. Nesting ObservableObject
s is fraught with other issues anyway, so it's best to avoid it):
struct Conversations: Decodable, Identifiable {
var id: String = ""
var users: [String] = [""]
var messages: [Message] = []
var hasUnreadMessage : Bool = false
}
To fix your Codable
issue, mark MessageType
as Codable
then use CodingKeys
to tell Swift that there won't be an id
to decode:
struct Message: Decodable, Identifiable {
enum CodingKeys : CodingKey {
case date, text, type
}
enum MessageType : Codable {
case Sent, Received
}
let id = UUID()
let date: Date
let text: String
let type: MessageType?
init(_ text: String, type: MessageType, date: Date) {
self.date = date
self.text = text
self.type = type
}
init(_ text: String, type: MessageType) {
self.init(text, type: type, date: Date())
}
}
(It's unclear to me whether there will always be a date
to decode -- if you run into issues with this, it's probably best to start a new question about it since it's tangential from the original issue anyway)