将 `.compactMap` 替换为自定义 `.decode`

问题描述

我为订阅 Firestore 文档创建了一个 secure-random -b输出类型是 DocumentSnapshot。

我是这样运行的...

FormatException: Missing argument for "base".
#0      Parser.validate (package:args/src/parser.dart:290:21)
#1      Parser.readNextArgAsValue (package:args/src/parser.dart:114:5)
#2      Parser.parseSoloOption (package:args/src/parser.dart:145:7)
#3      Parser.parse (package:args/src/parser.dart:86:11)
#4      ArgParser.parse (package:args/src/arg_parser.dart:326:42)
#5      main (file:///C:/Flutter/.pub-cache/hosted/pub.dartlang.org/encrypt-4.1.0/bin/secure-random.dart:18:29)
#6      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:281:32)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
Unhandled exception:
FormatException: Missing argument for "base".
#0      Parser.validate (package:args/src/parser.dart:290:21)
#1      Parser.readNextArgAsValue (package:args/src/parser.dart:114:5)
#2      Parser.parseSoloOption (package:args/src/parser.dart:145:7)
#3      Parser.parse (package:args/src/parser.dart:86:11)
#4      ArgParser.parse (package:args/src/arg_parser.dart:326:42)
#5      main (file:///C:/Users/user/AppData/Local/Pub/Cache/hosted/pub.dartlang.org/encrypt-4.1.0/bin/secure-random.dart:18:29)
#6      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:281:32)
#7      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)```
I have dart-sdk/bin into the environment variables,does anyone kNow why and how to solve it?

它的返回类型是 AnyPublisher,我想保留它。

这行得通,但我认为如果我可以在 Publisher 上使用 firestoreSubscription.subscribe(MyHashable(),"/user/1234567890") .compactMap { try? $0.data(as: UserDoc.self } 函数使其更像组合那样会很酷。

所以我创建了这个...

<UserDoc,Never>

所以现在我试试这个...

.decode

但是... 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)! } } 抛出而不是返回 environment.firestoreSubscription.subscribe(userSubscriptionID,"/user/\(state.userID)") .decode(type: UserDoc.self,decoder: FirestoreDecoder()) 。我想知道,是否可以丢弃抛出并认回​​到我在使用 TopLevelDecoder 方法时拥有的紧凑型地图解决方案?

或者……我应该继续使用 nil 吗?

另外…….decode 上的 .compactMap 会结束发布者吗?

解决方法

对 .decode 的抛出是否会结束发布者

是的,这将导致流失败 - 如果您订阅 Firestore 上的更改,这可能不是您想要的

您可以使用Combine 的catch 运算符来处理流中的失败

以您的示例为例,要忽略失败,您将捕获并返回 Empty 发布者。

environment.firestoreSubscription.subscribe(userSubscriptionID,"/user/\(state.userID)")
    .decode(type: UserDoc.self,decoder: FirestoreDecoder())
    .catch{ _ in Empty<UserDoc,Never>().eraseToAnyPublisher() }
,

好的,通过将 FirestoreDecoder 更改为这个...

import Firebase

public struct FirestoreDecoder {
    public static func decode<T>(_ type: T.Type) -> (DocumentSnapshot) -> T? where T: Decodable {{
        try? $0.data(as: type)
    }}
}

我能够做到...

firestoreSubscription.subscribe(MyHashable(),"/user/1234567890")
    .compactMap(FirestoreDecoder.decode(UserDoc.self))

这与我最初拥有的相似,但将对 Firestore 的依赖推送到单独的模块中。

??