Skip to content
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

Parse Document Fields & Create Minimally Viable Codable Implementation #26

Conversation

brianmichel
Copy link
Collaborator

@brianmichel brianmichel commented Nov 7, 2023

In order to effectively use the documents that come back from Firebase, we need to ensure that w can read the values out of the document and map them to Swift types as needed, but also need to make sure that we have a way to easily map the Firebase document into a Codable struct.

This was a little challenging as there is a seemingly reusable Firebase document parser in the FirebaseSharedSwift target within the Firebase iOS SDK package. However, due to an issue with SPM we can't easily access those file due to the way that binary targets are handled when adding a dependency (even if you aren't using any targets that requires those binary objects). Additionally, the Firebase team does not seem to want to entertain the work to break this target into it's own repo/package firebase/firebase-ios-sdk#12062.

The most straightforward solution seemed to be to copy the files we need into the project and annotate where things get copied in. I'd love a more stable way to do this (if folks have idea how to do this with CMake in a way that would be durable for folks cloning this package down I'm all ears!)

How To Test

  • Create a struct you'd like to map from an existing Firestore document.
  • Fetch the document and use the data(as ...) api to try to map the document to the struct.

Open Questions

  • Is there a better way to include the files we need from upstream?
  • I've included their license file in the directory which the files have been copy to ensure that we keep the license intact, but what does that mean about our license to swift-firebase?
  • Is there any way to write and run tests? It seems like the bugs with C++ interop make it impossible to run tests in this project. I'd like to write some tests for the parser code since it's a bit complicated and does a bunch of conversion of types to and from C++.

@@ -79,6 +83,8 @@ let SwiftFirebase =
"-Lthird_party/firebase-development/usr/libs/windows",
"-Lthird_party/firebase-development/usr/libs/windows/deps/app",
"-Lthird_party/firebase-development/usr/libs/windows/deps/app/external",
"-Xlinker",
"-ignore:4217"
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was mostly getting annoyed seeing these in the build logs. I see we ignore them on other builds so I felt it was safe to do it here.

Comment on lines +12 to +16
public typealias ServerTimestampBehavior = firebase.firestore.DocumentSnapshot.ServerTimestampBehavior
public typealias MapFieldValue = firebase.firestore.MapFieldValue

public typealias GeoPoint = firebase.firestore.GeoPoint
public typealias FieldValue = firebase.firestore.FieldValue
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These all had to become public types due to the surface area of the new set of codable APIs we've added.

return nil
}
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops need to fix the missing newlines


public enum FirestoreEncodingError: Error {
case encodingIsNotSupported(String)
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs new line

t is FieldValue ||
t is DocumentReference
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs missing newline


extension DocumentID: Equatable where Value: Equatable {}

extension DocumentID: Hashable where Value: Hashable {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs missing newline

let debugDescription = "Unable to encode \(valueDescription) directly in JSON. Use JSONEncoder.NonConformingFloatEncodingStrategy.convertToString to specify how the value should be encoded."
return .invalidValue(value, EncodingError.Context(codingPath: codingPath, debugDescription: debugDescription))
}
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs missing newline

func dataValue() -> Data
func arrayValue() -> [AnyHashable]?
func dictionaryValue() -> [String: AnyHashable]?
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs missing newline

Comment on lines +52 to +55
struct MapFieldValue_Workaround {
std::vector<std::string> keys;
std::vector<::firebase::firestore::FieldValue> values;
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type and the resulting _workaround apis are here because it seems that CxxDictionary conformance doesn't work well in Swift for Windows yet. I have a sample repo that shows the problem and need to file an issue on the Swift repo https://github.com/brianmichel/swift-cpp-interop-map-compatibility.

These are kind of ugly, but the MapFieldValue_Workaround type just breaks out the keys/values of a regular map into accessible vectors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant