firebase / firebase-ios-sdk

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

FirebaseDataEncoder that encode Data when calling to encode, returns Any instead of Data #14045

Open jesus-mg-ios opened 2 weeks ago

jesus-mg-ios commented 2 weeks ago

Description

Seems like there's a bug in the sign of FirebaseDataEncoder encoder method open func encode<T : Encodable>(_ value: T) throws -> Any { that should be open func encode<T : Encodable>(_ value: T) throws -> Data {

because it encodes data.

Any cannot be sendable whereas Data it is.

Thanks for your time.

Reproducing the issue

No response

Firebase SDK Version

11.3

Xcode Version

16.1

Installation Method

Swift Package Manager

Firebase Product(s)

Firestore, Functions

Targeted Platforms

iOS

Relevant Log Output

No response

If using Swift Package Manager, the project's Package.resolved

No response

If using CocoaPods, the project's Podfile.lock

No response

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.

jesus-mg-ios commented 2 weeks ago

I can see now why it returns Any. It doesn’t actually encode to Data; instead, it generates something like an NSDictionary, parses it as an AnyObject, and then returns it as Any, right?

If that's the case, it would be great to return a SendableType as a wrapper to manage it, and manage it internally when calling a function.

mortenbekditlevsen commented 2 weeks ago

It does encode. It encodes to a format that can be consumed by the realtime database, functions and firestore. Encoding does not impose any restrictions on the type of the encoded value.

It could probably be restricted to some sendable type though, but one could imagine that would require quite a bit of work.

Where would it be usable for the encoded value to be sendable?

jesus-mg-ios commented 2 weeks ago
let data = try firebaseEncoder.encode(dummyEncodableObject)
Task { @Sendable [weak function] in
   _ = try await function(#Call to the function#).call(data) // Capture of 'data' with non-sendable type 'Any' in a `@Sendable` closure; this is an error in the Swift 6 language mode 
}

Thanks for your reply! What I meant is that just by reading the name, it seems like FirebaseDataEncoder encodes to a Data type. For example, Foundation.JSONEncoder clearly encodes something to JSON data, being the representation Data type. So, the name FirebaseDataEncoder could be ambiguous, as it suggests it encodes something into "Firebase Data," with "data" potentially being interpreted as the Data type. A clearer, less ambiguous name could be FirebaseEncoder, which would suggest that the encoder prepares data for Firebase without implying its encoding to a specific Data type.

milaGGL commented 2 weeks ago

@jesus-mg-ios , I wonder what is the error in Swift 6 language mode. Feels like this is similar to the issue: https://github.com/firebase/firebase-ios-sdk/issues/13962

jesus-mg-ios commented 2 weeks ago

@milaGGL

 // Capture of 'data' with non-sendable type 'Any' in a `@Sendable` closure; this is an error in the Swift 6 language mode