Skip to content

Commit 25867e1

Browse files
author
Oleksii Dykan
authored
Merge pull request #43 from alickbass/support-firtimestamp
Add support for FirTimestamp
2 parents f1d465b + 0d4a779 commit 25867e1

4 files changed

Lines changed: 69 additions & 4 deletions

File tree

CodableFirebase/FirestoreDecoder.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ public protocol GeoPointType: FirestoreDecodable, FirestoreEncodable {
2020
init(latitude: Double, longitude: Double)
2121
}
2222

23+
public protocol TimestampType: FirestoreDecodable, FirestoreEncodable {
24+
init(date: Date)
25+
func dateValue() -> Date
26+
}
27+
2328
open class FirestoreDecoder {
2429
public init() {}
2530

@@ -76,3 +81,15 @@ extension FirestoreEncodable {
7681
throw DocumentReferenceError.typeIsNotSupported
7782
}
7883
}
84+
85+
extension TimestampType {
86+
public init(from decoder: Decoder) throws {
87+
let container = try decoder.singleValueContainer()
88+
self.init(date: try container.decode(Date.self))
89+
}
90+
91+
public func encode(to encoder: Encoder) throws {
92+
var container = encoder.singleValueContainer()
93+
try container.encode(self.dateValue())
94+
}
95+
}

CodableFirebaseTests/TestCodableFirebase.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ class TestCodableFirebase: XCTestCase {
9595
expectedValue: expected,
9696
dateEncodingStrategy: .secondsSince1970,
9797
dateDecodingStrategy: .secondsSince1970)
98+
99+
_testRoundTrip(of: TopLevelWrapper(FirTimestamp(date: Date(timeIntervalSince1970: seconds))),
100+
expectedValue: expected,
101+
dateEncodingStrategy: .secondsSince1970,
102+
dateDecodingStrategy: .secondsSince1970)
98103

99104
_testRoundTrip(of: OptionalTopLevelWrapper(Date(timeIntervalSince1970: seconds)),
100105
expectedValue: expected,
@@ -500,6 +505,22 @@ fileprivate struct Timestamp : Codable, Equatable {
500505
}
501506
}
502507

508+
fileprivate struct FirTimestamp : TimestampType, Equatable {
509+
let date: Date
510+
511+
init(date: Date) {
512+
self.date = date
513+
}
514+
515+
func dateValue() -> Date {
516+
return date
517+
}
518+
519+
static func == (_ lhs: FirTimestamp, _ rhs: FirTimestamp) -> Bool {
520+
return lhs.date == rhs.date
521+
}
522+
}
523+
503524
/// A simple referential counter type that encodes as a single Int value.
504525
fileprivate final class Counter : Codable, Equatable {
505526
var count: Int = 0

CodableFirebaseTests/TestCodableFirestore.swift

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,14 @@ class TestCodableFirestore: XCTestCase {
128128
XCTAssertEqual((try? FirestoreEncoder().encode(val)) as NSDictionary?, ["value": val.value])
129129
XCTAssertEqual(try? FirestoreDecoder().decode(TopLevelWrapper<DocumentReference>.self, from: ["value": val.value]), val)
130130
}
131-
131+
132+
func testEncodingTimestamp() {
133+
let timestamp = Timestamp(date: Date())
134+
let wrapper = TopLevelWrapper(timestamp)
135+
XCTAssertEqual((try? FirestoreEncoder().encode(wrapper)) as NSDictionary?, ["value": timestamp])
136+
XCTAssertEqual(try? FirestoreDecoder().decode(TopLevelWrapper<Timestamp>.self, from: ["value": timestamp]), wrapper)
137+
}
138+
132139
private func _testEncodeFailure<T : Encodable>(of value: T) {
133140
do {
134141
let _ = try FirestoreEncoder().encode(value)
@@ -195,10 +202,29 @@ fileprivate class GeoPoint: NSObject, GeoPointType {
195202
self.longitude = longitude
196203
}
197204

198-
static func == (lhs: Point, rhs: Point) -> Bool {
199-
return lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
205+
override func isEqual(_ object: Any?) -> Bool {
206+
guard let other = object.flatMap({ $0 as? GeoPoint }) else { return false }
207+
return latitude == other.latitude && longitude == other.longitude
200208
}
201209
}
202210

203211
// MARK: - ReferenceType
204212
fileprivate class DocumentReference: NSObject, DocumentReferenceType {}
213+
214+
// MARK: - Timestamp
215+
fileprivate class Timestamp: NSObject, TimestampType {
216+
let date: Date
217+
218+
required init(date: Date) {
219+
self.date = date
220+
}
221+
222+
func dateValue() -> Date {
223+
return date
224+
}
225+
226+
override func isEqual(_ object: Any?) -> Bool {
227+
guard let other = object.flatMap({ $0 as? Timestamp }) else { return false }
228+
return date == other.date
229+
}
230+
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,15 @@ Firestore.firestore().collection("data").document("one").getDocument { (document
8686
}
8787
```
8888

89-
### How to use `GeoPoint`, `DocumentRefence`, `FieldValue` in Firestore
89+
### How to use `GeoPoint`, `DocumentRefence`, `FieldValue`, `Timestamp` in Firestore
9090

9191
In order to use these 2 types with `Firestore`, you need to add the following code somewhere in your app:
9292

9393
```swift
9494
extension DocumentReference: DocumentReferenceType {}
9595
extension GeoPoint: GeoPointType {}
9696
extension FieldValue: FieldValueType {}
97+
extension Timestamp: TimestampType {}
9798
```
9899

99100
and now they become `Codable` and can be used properly with `FirestoreEncoder` and `FirestoreDecoder`.

0 commit comments

Comments
 (0)