Reputation: 5354
I have a custom model in swift and it has a property of type DocumentReference
I'm getting some data from a cloud function and then I'm trying to decode it back to my model.
DocumentReference
doesn't conform to Decodable by itself so I'm trying to write an extension for it.
I can not make it work since I keep getting this error:
Initializer requirement 'init(from:)' can only be satisfied by a 'required' initializer in the definition of non-final class 'DocumentReference'
Any idea how to make this work?
My extension:
import Firebase
extension DocumentReference: Decodable {
public convenience init(from decoder: Decoder) throws {
//
}
}
Existing model:
struct Notification: Identifiable, CollectionProtocol, DocumentProtocol {
var id = UUID()
var documentReference: DocumentReference
var receiverID: String
var type: String
var createdAt: Date
var requestReference: DocumentReference?
var request: Request?
init(document: DocumentSnapshot) {
self.documentReference = document.reference
self.requestReference = document["requestReference"] as? DocumentReference ?? Firestore.firestore().document("")
self.receiverID = document["receiverID"] as? String ?? ""
self.type = document["type"] as? String ?? ""
self.createdAt = (document["createdAt"] as? Timestamp)?.dateValue() ?? Date()
}
}
Upvotes: 2
Views: 1270
Reputation: 51891
The class DocumentReference is not final which means that it could possibly be sub-classed but without the sub class conforming to Codable. So this would leave to an unknown state if init(from decoder: Decoder)
in your extension was called.
One workaround could be to create a wrapper struct with its own init(from decoder: Decoder)
and then do your decoding of DocumentReference there.
Example:
struct Wrapped: Decodable {
let docRef: DocumentReference
public init(from decoder: Decoder) throws {
let container = try decoder....
// add the decoding code here for DocumentReference
}
}
Upvotes: 1
Reputation: 12385
NS_SWIFT_NAME(DocumentReference)
@interface FIRDocumentReference : NSObject
/** :nodoc: */
- (instancetype)init
__attribute__((unavailable("FIRDocumentReference cannot be created directly.")));
DocumentReference
(FIRDocumentReference
) cannot be instantiated directly; it has no available initializers. To implement the required init, you'd have to do that in the declaration of the class itself.
If you want to conveniently instantiate custom objects from Firestore data, consider a failable initializer that takes a [String: Any]
argument. If you just want to encode/decode the reference itself, consider encoding/decoding the String
value of the location itself (the collection and document names) and then using that to reconstruct the DocumentReference
.
Upvotes: 1