firebase / firebase-ios-sdk

Firebase SDK for Apple App Development
https://firebase.google.com
Apache License 2.0
5.55k stars 1.45k forks source link

[FR]: Support for CodableWithConfiguration #13552

Open Supereg opened 2 weeks ago

Supereg commented 2 weeks ago

Description

  1. Firestore currently supports passing Codable ( Encodable or Decodable respectively) types when retrieving or setting the data of a document. iOS 17 introduced a new set of protocols: CodableWithConfiguration (a type alias for EncodableWithConfiguration & DecodableWithConfiguration) that allow passing an additional, fully typed Configuration type alongside the encode and decode methods. New encode(_:configuration:) and decode(_:configuration:) methods on e.g. the JSON coders allow to pass a configuration alongside the type/value.
  2. It is currently not possible to work with CodableWithConfiguration-conforming types when using Firestore without the need to create additional wrapper types.
  3. Similar to Codable types, Firestore should accept CodableWithConfiguration types by allowing to pass an additional configuration argument.

API Proposal

The following additive API changes are proposed. They are expressed as Swift Extensions with the implementation body missing.

@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
extension Firestore.Encoder {
    public func encode<T: EncodableWithConfiguration>(
        _ value: T,
        configuration: T.EncodingConfiguration
    ) throws -> [String: Any]

    public func encode<T: EncodableWithConfiguration, C: EncodingConfigurationProviding>(
        _ value: T,
        configuration: C.Type
    ) throws -> [String: Any] where T.EncodingConfiguration == C.EncodingConfiguration
}

@available(macOS 12, iOS 15, tvOS 15, watchOS 8, *)
extension Firestore.Decoder {
    public func decode<T: DecodableWithConfiguration>(
        _ type: T.Type,
        from data: Any,
        configuration: T.DecodingConfiguration
    ) throws -> T

    public func decode<T: DecodableWithConfiguration, C: DecodingConfigurationProviding>(
        _ type: T.Type,
        from data: Any,
        configuration: C.Type
    ) throws -> T where T.DecodingConfiguration == C.DecodingConfiguration
}

Additionally, one would need to add additional overloads for the factious setData, data, getDocument, setDocument methods in types like DocumentReference, DocumentSnapshot, CollectionReference, Transaction and WriteBatch (might be missing some). Each of them would ned similar adjustments of using the new protocols and accepting an additional configuration parameter that is forwarded to the Encoder/Decoder.

Firebase Product(s)

Firestore

google-oss-bot commented 2 weeks ago

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

MarkDuckworth commented 2 weeks ago

@Supereg, thank you for the feature request. I'll review this with the team.

MarkDuckworth commented 2 weeks ago

Can you tell us more about your use case(s)? Thanks!

Supereg commented 2 weeks ago

@Supereg, thank you for the feature request. I'll review this with the team.

Sounds great, thank you 🚀

Can you tell us more about your use case(s)? Thanks!

I might just point you to our real-world example. We have a framework that provides typed-storage AccountDetails. In order to decode, we need the Swift types that make up the keys of the type-storage to know how to decode the value of an entry. See our DecodableWithConfiguration here. The AccountDetails type is stored in Firestore (see here).

This is a small overview of our specific use case. Feel free to reach out, if you want me to go into more detail or need a broader description of potential use cases.