Skip to content

Commit ec22c16

Browse files
author
Oleksii Dykan
authored
Merge pull request #17 from alickbass/field-type-support
Field type support
2 parents e6947de + 8279c70 commit ec22c16

File tree

7 files changed

+23
-14
lines changed

7 files changed

+23
-14
lines changed

CodableFirebase/Decoder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class _FirebaseDecoder : Decoder {
1313
struct _Options {
1414
let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy?
1515
let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy?
16-
let skipGeoPointAndReference: Bool
16+
let skipFirestoreTypes: Bool
1717
let userInfo: [CodingUserInfoKey : Any]
1818
}
1919

@@ -1230,7 +1230,7 @@ extension _FirebaseDecoder {
12301230
} else if T.self == Decimal.self || T.self == NSDecimalNumber.self {
12311231
guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil }
12321232
decoded = decimal as! T
1233-
} else if options.skipGeoPointAndReference && (T.self is GeoPointType.Type || T.self is DocumentReferenceType.Type) {
1233+
} else if options.skipFirestoreTypes && (T.self is FirestoreDecodable.Type) {
12341234
decoded = value as! T
12351235
} else {
12361236
self.storage.push(container: value)

CodableFirebase/Encoder.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class _FirebaseEncoder : Encoder {
1313
struct _Options {
1414
let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy?
1515
let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy?
16-
let skipGeoPointAndReference: Bool
16+
let skipFirestoreTypes: Bool
1717
let userInfo: [CodingUserInfoKey : Any]
1818
}
1919

@@ -383,7 +383,7 @@ extension _FirebaseEncoder {
383383
return try self.box((value as! Data))
384384
} else if T.self == URL.self || T.self == NSURL.self {
385385
return self.box((value as! URL).absoluteString)
386-
} else if options.skipGeoPointAndReference && (value is GeoPointType || value is DocumentReferenceType) {
386+
} else if options.skipFirestoreTypes && (value is FirestoreEncodable) {
387387
guard let value = value as? NSObject else {
388388
throw DocumentReferenceError.typeIsNotNSObject
389389
}

CodableFirebase/FirebaseDecoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ open class FirebaseDecoder {
5353
let options = _FirebaseDecoder._Options(
5454
dateDecodingStrategy: dateDecodingStrategy,
5555
dataDecodingStrategy: dataDecodingStrategy,
56-
skipGeoPointAndReference: false,
56+
skipFirestoreTypes: false,
5757
userInfo: userInfo
5858
)
5959
let decoder = _FirebaseDecoder(referencing: container, options: options)

CodableFirebase/FirebaseEncoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ open class FirebaseEncoder {
5757
let options = _FirebaseEncoder._Options(
5858
dateEncodingStrategy: dateEncodingStrategy,
5959
dataEncodingStrategy: dataEncodingStrategy,
60-
skipGeoPointAndReference: false,
60+
skipFirestoreTypes: false,
6161
userInfo: userInfo
6262
)
6363
let encoder = _FirebaseEncoder(options: options)

CodableFirebase/FirestoreDecoder.swift

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,18 @@
88

99
import Foundation
1010

11-
public protocol GeoPointType: Codable {
11+
public protocol FirestoreDecodable: Decodable {}
12+
public protocol FirestoreEncodable: Encodable {}
13+
14+
public typealias DocumentReferenceType = FirestoreDecodable & FirestoreEncodable
15+
public typealias FieldValueType = FirestoreEncodable
16+
17+
public protocol GeoPointType: FirestoreDecodable, FirestoreEncodable {
1218
var latitude: Double { get }
1319
var longitude: Double { get }
1420
init(latitude: Double, longitude: Double)
1521
}
1622

17-
public protocol DocumentReferenceType: Codable {}
18-
1923
open class FirestoreDecoder {
2024
public init() {}
2125

@@ -25,7 +29,7 @@ open class FirestoreDecoder {
2529
let options = _FirebaseDecoder._Options(
2630
dateDecodingStrategy: nil,
2731
dataDecodingStrategy: nil,
28-
skipGeoPointAndReference: true,
32+
skipFirestoreTypes: true,
2933
userInfo: userInfo
3034
)
3135
let decoder = _FirebaseDecoder(referencing: container, options: options)
@@ -61,11 +65,13 @@ enum DocumentReferenceError: Error {
6165
case typeIsNotNSObject
6266
}
6367

64-
extension DocumentReferenceType {
68+
extension FirestoreDecodable {
6569
public init(from decoder: Decoder) throws {
6670
throw DocumentReferenceError.typeIsNotSupported
6771
}
68-
72+
}
73+
74+
extension FirestoreEncodable {
6975
public func encode(to encoder: Encoder) throws {
7076
throw DocumentReferenceError.typeIsNotSupported
7177
}

CodableFirebase/FirestoreEncoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ open class FirestoreEncoder {
2929
let options = _FirebaseEncoder._Options(
3030
dateEncodingStrategy: nil,
3131
dataEncodingStrategy: nil,
32-
skipGeoPointAndReference: true,
32+
skipFirestoreTypes: true,
3333
userInfo: userInfo
3434
)
3535
let encoder = _FirebaseEncoder(options: options)

README.md

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

89-
### How to use `GeoPoint` and `DocumentRefence` in Firestore
89+
### How to use `GeoPoint`, `DocumentRefence`, `FieldValue` 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 {}
96+
extension FieldValue: FieldValueType {}
9697
```
9798

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

101+
***PLEASE NOTE*** that as `FieldValue` is only used to [`setData()` and `updateData()`](https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/FieldValue), it only adopts the `Encodable` protocol.
102+
100103
## Integration
101104

102105
### CocoaPods (iOS 9+)

0 commit comments

Comments
 (0)