Skip to content

Instantly share code, notes, and snippets.

@bsansouci
Created January 5, 2021 18:45
Show Gist options
  • Save bsansouci/760e042d6fccac8bb8dfb76dd7d0b3dc to your computer and use it in GitHub Desktop.
Save bsansouci/760e042d6fccac8bb8dfb76dd7d0b3dc to your computer and use it in GitHub Desktop.
Firebase bindings for ReScript with new import syntax
@bs.val external prod: bool = "process.env.PROD"
// Effectful imports
%raw("require('firebase/auth')")
%raw("require('firebase/functions')")
%raw("require('firebase/firestore')")
type userT = {
displayName: string,
email: string,
photoURL: string,
uid: string,
}
type authT<'a> = {currentUser: option<userT>}
type appT
// @bs.module("firebase/app") external initializeNamedApp: (Js.t<'a>, string) => unit = "initializeApp"
// @bs.module("firebase/app") external authConfig: Js.t<'a> = "auth"
// @bs.module("firebase/app") external defaultAuth: unit => authT<'a> = "auth"
// @bs.module("firebase/app") external app: string => appT = "app"
import {
initializeApp as initializeNamedApp: (Js.t<'a>, string) => unit,
auth as authConfig: Js.t<'a>,
auth as defaultAuth: unit => authT<'a>,
app: string => appT
} from "firebase/app"
type authUIT
// @bs.module("firebaseui") @bs.new @bs.scope("auth") external authUI: authT<'a> => authUIT = "AuthUI"
// @bs.module("firebaseui") @bs.new @bs.scope("auth") external authUIWithName: (authT<'a>, string) => authUIT = "AuthUI"
import {
@bs.new
\"auth.AuthUI" as authUI: authT<'a> => authUIT,
@bs.new
\"auth.AuthUI" as authUIWithName: (authT<'a>, string) => authUIT,
} from "firebaseui"
@bs.send
external onAuthStateChanged: (authT<'a>, Js.Nullable.t<userT> => unit) => unit =
"onAuthStateChanged"
@bs.send external getIdToken: userT => Js.Promise.t<string> = "getIdToken"
let default = () => app("[DEFAULT]")
let prodApp = () => app("brief-staging")
@bs.send external auth: appT => authT<'a> = "auth"
type firestoreT<'a> = {id: string}
@bs.send external firestore: appT => firestoreT<'a> = "firestore"
@bs.send external start: (authUIT, string, Js.t<'a>) => unit = "start"
type functionsT
@bs.send external functions: appT => functionsT = "functions"
@bs.send external httpsCallable: (functionsT, string, . 'a) => Js.Promise.t<'b> = "httpsCallable"
@gentype
type timestamp = {
seconds: float,
nanoseconds: float,
toMillis: unit => float,
toDate: (. unit) => Js.Date.t,
}
// [@gentype]
module Timestamp = {
// @gentype.import(("firebase/app", "firestore.Timestamp.fromMillis"))
// @bs.module("firebase/app")
// @bs.scope(("firestore", "Timestamp"))
// external fromMillis: float => timestamp = "fromMillis"
// @gentype.import(("firebase/app", "firestore.Timestamp.fromDate"))
// @bs.module("firebase/app")
// @bs.scope(("firestore", "Timestamp"))
// external fromDate: Js.Date.t => timestamp = "fromDate"
import {
@gentype.import(("firebase/app", "firestore.Timestamp.fromMillis"))
\"firestore.Timestamp.fromMillis" as fromMillis: float => timestamp
@gentype.import(("firebase/app", "firestore.Timestamp.fromMillis"))
\"firestore.Timestamp.fromeDate" as fromDate: Js.Date.t => timestamp
} from "firebase/app"
}
module Firestore = {
type metadataT = {hasPendingWrites: option<bool>}
type refT = {
id: string,
path: string,
}
type singleDocumentT = {
metadata: option<metadataT>,
exists: bool,
@bs.as("ref")
ref_: refT,
}
type multipleDocumentsT = {
docs: Js.Array2.t<singleDocumentT>,
metadata: option<metadataT>,
empty: bool,
}
@bs.send
external collection: (firestoreT<singleDocumentT>, string) => firestoreT<multipleDocumentsT> =
"collection"
@bs.send external data: singleDocumentT => 'a = "data"
@bs.send
external create: (firestoreT<singleDocumentT>, string) => firestoreT<singleDocumentT> = "create"
@bs.send
external doc: (firestoreT<multipleDocumentsT>, string) => firestoreT<singleDocumentT> = "doc"
@bs.send
external orderBy: (
firestoreT<multipleDocumentsT>,
string,
string,
) => firestoreT<multipleDocumentsT> = "orderBy"
@bs.send
external where: (
firestoreT<multipleDocumentsT>,
string,
string,
string,
) => firestoreT<multipleDocumentsT> = "where"
@bs.send
external limit: (firestoreT<multipleDocumentsT>, int) => firestoreT<multipleDocumentsT> = "limit"
@bs.send external makeDoc: firestoreT<multipleDocumentsT> => firestoreT<singleDocumentT> = "doc"
@bs.send external get: firestoreT<'a> => Js.Promise.t<'a> = "get"
@bs.send external set: (firestoreT<'a>, Js.t<'b>) => Js.Promise.t<'a> = "set"
@bs.send
external setWithConfig: (firestoreT<'a>, Js.t<'b>, {"merge": bool}) => Js.Promise.t<'a> = "set"
@bs.send external delete: firestoreT<singleDocumentT> => Js.Promise.t<unit> = "delete"
@bs.send external update: (firestoreT<'a>, Js.t<'b>) => Js.Promise.t<'a> = "update"
@bs.send
external subcollection: (firestoreT<singleDocumentT>, string) => firestoreT<multipleDocumentsT> =
"collection"
type changesT = {
@bs.as("type")
type_: string,
doc: singleDocumentT,
}
@bs.send external docChanges: multipleDocumentsT => Js.Array2.array_like<changesT> = "docChanges"
@bs.send
external singleDocChanges: singleDocumentT => Js.Array2.array_like<changesT> = "docChanges"
@bs.send external onSnapshot: (firestoreT<'a>, (. 'a) => unit, . unit) => unit = "onSnapshot"
@bs.send
external docData: singleDocumentT => 'a = "data"
type transactionT
@bs.send
external runTransaction: (firestoreT<'a>, transactionT => Js.Promise.t<'a>) => Js.Promise.t<'a> =
"runTransaction"
@bs.send
external transactionUpdate: (transactionT, singleDocumentT, Js.t<'a>) => transactionT = "update"
}
module FieldValue = {
type fieldValue
// @bs.val @bs.module("firebase/app") @bs.scope(("firestore", "FieldValue"))
// external delete: unit => fieldValue = "delete"
// @bs.val @bs.module("firebase/app") @bs.scope(("firestore", "FieldValue")) @bs.variadic
// external arrayUnion: array<string> => fieldValue = "arrayUnion"
// @bs.val @bs.module("firebase/app") @bs.scope(("firestore", "FieldValue")) @bs.variadic
// external arrayRemove: array<string> => fieldValue = "arrayRemove"
// @bs.val @bs.module("firebase/app") @bs.scope(("firestore", "FieldValue"))
// external serverTimestamp: unit => fieldValue = "serverTimestamp"
import {
\"firestore.FieldValue.delete" as delete: unit => fieldValue,
\"firestore.FieldValue.arrayUnion" as arrayUnion: unit => fieldValue,
\"firestore.FieldValue.arrayRemove" as arrayRemove: unit => fieldValue,
\"firestore.FieldValue.serverTimestamp" as serverTimestamp: unit => fieldValue,
} from "firebase/app"
}
module Storage = {
type storageT
type docrefT = {getDownloadURL: (. unit) => Js.Promise.t<string>}
type snapshotT = {
@bs.as("ref")
ref_: docrefT,
}
type refT
// @bs.module("firebase/app") external storage: unit => storageT = "storage"
import {
storage: unit => storageT,
} from "firebase/app"
@bs.send external ref_: storageT => refT = "ref"
@bs.send external child: (refT, string) => refT = "child"
type fileT = {name: string}
@bs.val external createObjectURL: fileT => string = "URL.createObjectURL"
@bs.send external put: (refT, fileT) => Js.Promise.t<snapshotT> = "put"
type blobT = {
name: string,
@bs.as("type")
type_: string,
}
@bs.send external putBlob: (refT, blobT) => Js.Promise.t<snapshotT> = "put"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment