Last active
August 29, 2020 23:41
-
-
Save psilospore/e407beb6a5a38a68e8fa9e4335daafcf to your computer and use it in GitHub Desktop.
Using io-ts with Firestore's timestamp data type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Firestore} from "@google-cloud/firestore" | |
import { firestore as firestoreAdmin } from 'firebase-admin' | |
import {foldMap} from 'fp-ts/lib/Array' | |
import {pipe} from 'fp-ts/lib/pipeable' | |
import {monoidSum} from 'fp-ts/lib/Monoid' | |
import {flatMap, some as exists} from 'lodash' | |
import * as io from 'io-ts' | |
import { Timestamp } from '@google-cloud/firestore' | |
type FirestoreTimestampStruct = { | |
_seconds: number | |
/** | |
* Danger: I've seen this set to 0. Not sure if we need to enable this somehow. | |
*/ | |
_nanoseconds: number | |
} | |
/** | |
* Represents a Firestore Timestamp | |
* | |
* Credit to a similar example for a date: | |
* https://github.com/gcanti/io-ts/blob/master/index.md#custom-types | |
*/ | |
export const FirestoreTimestampCodec: io.Type< | |
Timestamp, | |
FirestoreTimestampStruct | |
> = new io.Type<Timestamp, FirestoreTimestampStruct>( | |
'Timestamp', | |
(u): u is Timestamp => u instanceof Timestamp, | |
(u: unknown, c) => { | |
try { | |
const t = u as FirestoreTimestampStruct | |
return io.success( | |
new Timestamp(t._seconds, t._nanoseconds), | |
) | |
} catch { | |
return io.failure(u, c) | |
} | |
}, | |
(a) => ({ | |
_seconds: a.seconds, | |
_nanoseconds: a.nanoseconds, | |
}), | |
) | |
console.log(FirestoreTimestampCodec.decode({ | |
_seconds: 15252152, | |
_nanoseconds: 0 //ignores this | |
})) | |
const DocCodec = io.type({ | |
timestamp: FirestoreTimestampCodec | |
}) | |
export type Doc = io.TypeOf<typeof DocCodec> | |
const firestore = new Firestore({ | |
projectId: 'yourproject' | |
}) | |
// A document with reference a and a property named timestamp is set to some typestamp | |
firestore.collection("test").doc("a").get().then((doc) => { | |
console.log(DocCodec.decode(doc.data())) | |
//Setting document update typechecks | |
const newData: Doc = { | |
timestamp: firestoreAdmin.Timestamp.now() | |
} | |
doc.ref.set(newData).then((writeRes) => console.log(writeRes), console.error) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment