I have created an AnyPublisher
for subscribing to Firestore documents and the Output type is a DocumentSnapshot.
I run it like this...
firestoreSubscription.subscribe(MyHashable(), "/user/1234567890")
.compactMap { try? $0.data(as: UserDoc.self }
The return type of this is <UserDoc, Never>
which I want to keep.
This worked but I thought it would be cool if I could use the .decode
function on Publisher to make it a bit more Combiney.
So I created this...
public struct FirestoreDecoder: TopLevelDecoder {
public init() {}
public typealias Input = DocumentSnapshot
public func decode<T>(_ type: T.Type, from: DocumentSnapshot) throws -> T where T : Decodable {
try! from.data(as: type)!
}
}
So now I try this...
environment.firestoreSubscription.subscribe(userSubscriptionID, "/user/\(state.userID)")
.decode(type: UserDoc.self, decoder: FirestoreDecoder())
But... TopLevelDecoder
throws rather than returning nil
. I wonder, is it possible to throw away the throws and default back to my compact map solution that I had whilst using the .decode
method?
Or... should I just keep using the .compactMap
?
Also... will the throw
on the .decode
end the publisher?
OK, by changing the FirestoreDecoder
to this...
import Firebase
public struct FirestoreDecoder {
public static func decode<T>(_ type: T.Type) -> (DocumentSnapshot) -> T? where T: Decodable {{
try? $0.data(as: type)
}}
}
I was able to do...
firestoreSubscription.subscribe(MyHashable(), "/user/1234567890")
.compactMap(FirestoreDecoder.decode(UserDoc.self))
Which is similar to what I had in the first place but pushes the dependency on Firestore
out to the separate module.
👍🏻