Home > Enterprise >  Argument passed to call that takes no arguments when mapping firebase fetch call
Argument passed to call that takes no arguments when mapping firebase fetch call

Time:10-08

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 ObservableObjects 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)

  • Related