-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for object serialization in Firestore #627
Comments
@firebase-oss-bot I did modified my post to get more clear. |
Hi! Thanks for writing in. Due to the way Firestore is released (as a part of the Firebase iOS SDK, built by Google) the Firestore client library is still an Objective-C project. We include annotation macros (e.g. There should be nothing that stops you from declaring your own extensions though, something like extension DocumentSnapshot: Decodable {
init(from: Decoder) {
// ...
}
} However before you do that, what benefit are you hoping to get from using Codable objects? We are looking into being able to build swift extensions but it's not going to happen anytime in the short term. If there's a really good use case for this it could help us prioritize this work. |
Hello. Thanks for response. Unfortunately currently 'Decodable' cannot be automatically synthesized. DocumentSnaphot can not inherit from Decodable. After doing it I am getting this error:
|
Right you'd need to implement The first problem you'll encounter though is that DocumentSnapshots contain types that are tied to the Firestore instance that created them (e.g. DocumentReference). The snapshot itself can navigate back to a document reference too. This means snapshots don't really exist disconnected from the instance. So outside of some really compelling use case this doesn't seem like a feature we'd add. Why are you trying to make snapshots Codable? |
Thanks for your answer. Here is two reasons to use Codable:
|
I have to agree with @ramunasjurgilas about adapting to modern implementation. Decodable/encodable was all the rage at WWDC 2017. Sure, we can live without it, but the whole thing with Swift is that it's supposed to be beautiful to a certain extent. And manually decoding JSON just adds a bunch of bloat. Still love Firebase tho. |
I agree, I am learning how to code, and it is infuriating knowing that the new releases (codable, MusicKit) are the future but I am still having to first learn the old ways since there is not adequate documentation and also lag in implementation in situations like these. |
I would have to say that if you’re new to code you will benefit more from doing it the old way than having all the shiny, glitzy tools of the most modern sdks and apis so have heart. Firebase offers you plenty of leg ups that no other tools out there provide. I’m only complaining about codeables because of my uncontrollable OCD to write the cleanest code that I possibly can. 😂
…On Feb 3, 2018, 9:27 AM -0600, kaynelynn ***@***.***>, wrote:
I agree, I am learning how to code, and it is infuriating knowing that the new releases (codable, MusicKit) are the future but I am still having to first learn the old ways since there is not adequate documentation and also lag in implementation in situations like these.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or mute the thread.
|
I think I misunderstood the original request here. It's not that you want DocumentSnapshots themselves to be Codable/Decodable (since that would only give you the ability to serialize them to and from bytes which isn't useful). What this is about is that you want an Encoder and Decoder for Snapshots that would map between your custom objects and snapshots. We've had something like this on our radar for a bit. Essentially we want to provide an equivalent to the Android DocumentSnapshot.toObject. |
Hi guys! Maybe it's a bit off-topic, but I have written a small library to decode the Firestore's |
That's not off topic at all, and very cool! Would you be willing to work with us to incorporate something similar directly into the Firestore API? |
@alickbass Myself started to write something like this. Thanks for sharing. It will save a lot of time. I could look into your library. |
@wilhuff Sure! I would love to contribute! Maybe we could start a separate thread and discuss the details for the design and ideas on how to incorporate it into Firestore API? |
@wilhuff where would be an appropriate place to start the discussion? Is it here in github issues or in Firebase talk google group? |
Here is fine. |
Okay guys, here are several things I would like to discuss:
Once we clarify all these points, I could draft a PR with the initial proposal 🙃 |
Broadly my goal for this would be to add to the surface API of Firestore such that something like the following becomes possible: class Model : Codable {
}
// read
let snap: DocumentSnapshot = // …
let model = snap.data(as:Model.self)
// write
let ref: DocumentReference = // …
ref.setData(from:model) { error? in /* … */ } The equivalent API that already exists on Android looks like this: // read
DocumentSnapshot snap = // ...
Model model = snap.toObject(Model.class); // inferred type T
// write
DocumentReference ref = // ...
ref.set(model); The benefit of building this into the APIs is that the result of the encode/decode is not specified giving us the opportunity to optimize this later. Note that the dictionary form we accept and emit is temporary. We convert to an internal form immediately so keeping the encoder internal allows us to eventually convert directly to the internal form. However, I wouldn't recommend attempting that now because we're rewriting the internals of the client in C++ (to make it easier to directly support Unity and desktop use). The internal representation is currently FSTObjectValue but we're migrating to model::FieldValue. So if you accept this as a reasonable direction I think this leads to some answers to your questions:
Another area we have to figure out is exactly how to build this. Firebase still supports users using Xcode 8 and Objective-C-only clients so this probably needs to be in a non-default subspec of the FirebaseFirestore pod. The intersection of this and how we ship our production (pre-built) pods creates an interesting problem to solve but I think it's tractable. I'll get back to you on this part. |
Thanks @wilhuff for such a quick reply! I think I have quite some information to start working on some initial proposal. I will take your desired code as a starting point and will submit a PR. I will start with using dictionary as before and once there will be more stable internal API, we could rewrite it to direct internal form. As for the version of swift, I will add annotations to make it available only from swift version 4, so it shouldn't be a problem. For now I will leave aside the |
I'd suggest actually that the very last piece we want is the top-level API changes. These commit us to shipping the feature and will be blocked on API review. We can make a number of smaller commits to master before that point otherwise. |
Hi @wilhuff and @morganchen12 ! So I have started working on it already, however, I immediately bumped into issues with adding a Swift file to the |
Hi @alickbass It's unfortunate that there is not yet proper CocoaPods support for mixed languages in static frameworks. Hopefully we'll get that added in the next few months. In the meantime, the bridging header workaround should work. Do you understand what is different from the project described there? If you get stuck, please share a branch that demonstrates the problem and I'll take a look this week. Alternatively, if you want to avoid dealing with an immature part of CocoaPods, you could do your implementation as a separate |
@wilhuff Any news? ABI stability is there in the mean time. |
There's been some progress on this (see #3198 and #3231). We're not yet ready for a release but this is coming along. It's possible to kick the tires on this now if you're really enterprising, but we don't have instructions written up for how to do that yet. As a side note, ABI stability going forward is good but it's going to be quite some time before we can require e.g. iOS 12.2 as the minimum supported version. |
@wilhuff Please ping me if there are open tickets that I could help you with. Also on a side note: How feasible do you think would it be to maintain a 12.2 targeted Swift-only Framework? Like the one @alickbass started working on? |
Nearly everything required to make this work has landed. We're still wrangling a few internal things and haven't yet tested on anything but iOS, but you can try it out. Try adding this to your Podfile: pod 'FirebaseFirestoreSwift', :podspec => 'https://raw.githubusercontent.com/firebase/firebase-ios-sdk/master/FirebaseFirestoreSwift.podspec' In any Swift source where you want to use this add: import FirebaseFirestoreSwift We have no docs yet, so the swift source is really all you'll have to go on. Let us know how it goes! |
@wilhuff cool, I'll give it a try as soon as I get the chance. Will report |
@wilhuff thanks for this. I'm having trouble with the pod installation, the podspec doesn't seem to match the proper tag/branch. Can you please update?
|
That's weird! I see that too. Try adding this instead:
|
@wilhuff Thanks, this looks to be working well. I did have an issue that a |
@grennis Thanks very much for giving this a spin and contributing that bugfix! Holler if you have any other feedback or issues. |
@mikelehen Will do. So far everything else is working well for me. Thanks! |
@wilhuff Is it possible to decode the reference ID? I see the |
Before we talk about anything else: With regard to Codable though it doesn't sound like you're asking about this. It sounds like you're asking to be able to recover the ID of the document itself? If so, we haven't implemented this yet because it's tricky. By default Codable expects there to be a correspondence between the input values--the Firestore document data--and the resulting Codable object. This is a case were we'll have to add something to carry that out of band. Would a |
Yeah, I'm looking for ID of the document after it's been created/retrieved. I think your idea to solve that issue is great.v :) |
@wilhuff Thanks for implementing FirebaseFirestoreSwift to support Codable protocol. From my understanding here is missing addSnapshotListenerWithIncludeMetadataChanges function. This function could support Encodable protocol as well.
|
The way this works is that you can ask the snapshots you receive from a listener to convert themselves to a codable object. So, for example, if you have a type let docRef: DocumentReference = // ...
docRef.addSnapshotListener { snapshot, error in
// handle error
let value = snapshot.data(as: MyCodableType.self)
} |
https://github.com/alickbass/CodableFirebase could help. |
can't wait for this feature to become available in the main pod, codable support sounds very important. Thanks for the work! |
pod 'Firebase/Core'
pod 'Firebase/Firestore'
pod 'FirebaseFirestoreSwift' This is a separate module, so importing Firestore with Codable support works like this: import Firebase
import FirebaseFirestoreSwift If you're using Swift 5.1 (from Xcode 11) this includes several property wrappers to help make reading and writing documents easier:
If you're upgrading from the pre-release FirebaseFirestoreSwift (version 0.1) a few things have changed:
Try it out and let us know how it goes! |
I'm not sure if this is the right place to bring this up, as I am still getting used to contributing to GitHub, but I notice that the data method now returns an optional, even for QueryDocumentSnapshots, which are guaranteed to have a data object. If the method already throws, why does it need to return an optional? I implemented a fix in my own project by creating an extension on QueryDocumentSnapshot itself, and adding this method: public func data<T: Decodable>(decodedAs type: T.Type, However, I feel like it would be cleaner if it was able to use the same data(as: ...) signature as is provided for DocumentSnapshot, and I cannot do that because the compiler tells me that overriding methods in extensions is not supported. That said, not having to unwrap something that will never be nil seems worthwhile to me, but I honestly understand if I'm alone on that. |
The reason we don’t provide that override of the return type is for exactly the reason you’re seeing. Extensions are limited in what they can do and this is one area where our approach of extending the Objective-C SDK leads to a suboptimal result. Unfortunately there isn’t anything we can do to fix it short of adding another method. |
Currently getDocuments function do not supports Codable/Decodable protocol ( It is Swift 4 biggest advantage). Currently I need to write wrapper which uses Codable protocols. Below is example (Example: 2) how I did it. Without using Codable/Decodable I would need to pars responses in old way using dictionary manner as shown in example: 1. It is overkill do not use Codable protocol.
My question is what stop Firebase engineers add Codable advantages to SDK?
The text was updated successfully, but these errors were encountered: