diff --git a/README.md b/README.md index 6059edc..39bd4eb 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ Add it to `bsconfig.json` ## Initialize app ```reason +open BsFirebase; + [@bs.module] external firebaseConfig: firebaseConfig = "./config/firebase-config.json"; @@ -28,11 +30,15 @@ firebase->initializeApp(firebaseConfig); ## Authentication -```reason -open BsFirebase; +First include the 'firebase/auth' module in our app bundle. + BsFirebase.Auth.(require); + +#### Watch for user change + +```reason firebase -->auth() +->auth ->Auth.onAuthStateChanged(user => { switch (user->Js.Nullable.toOption) { | None => () @@ -45,9 +51,35 @@ firebase } }); -let signInWithGoogle = () => firebase->auth()->Auth.signInWithPopup(Auth.Provider.google()); -let signInWithEmailAndPassword = (~email, ~password) => firebase->auth()->Auth.signInWithEmailAndPassword(~email, ~password); -let signOut = () => firebase->auth()->Auth.signOut(); +let signInWithGoogle = () => firebase->auth->Auth.signInWithPopup(Auth.Provider.google()); +let signInWithEmailAndPassword = (~email, ~password) => firebase->auth->Auth.signInWithEmailAndPassword(~email, ~password); +let signOut = () => firebase->auth->Auth.signOut(); +``` + +#### Sign in etc + +```reason +Js.Promise.( + BsFirebase.(firebase->auth->Auth.signInWithEmailAndPassword(~email, ~password)) + |> then_(value => { + Js.log(value); + Js.Promise.resolve(value); + }) + |> ignore +); +``` + +#### Get token + +```reason +Js.Promise.( + firebase->auth->Auth.currentUser->Auth.User.getIdToken() + |> then_(value => { + Js.log(value); + Js.Promise.resolve(value); + }) + |> ignore +); ``` ## Firestore @@ -57,7 +89,7 @@ let signOut = () => firebase->auth()->Auth.signOut(); ```reason let fetchAll = () => { firebase - ->firestore() + ->firestore ->Firestore.collection("mycollection") ->Firestore.Collection.get() |> Js.Promise.then_(querySnapshot => @@ -80,12 +112,12 @@ let fetchAll = () => { ```reason let fetchItem = (id) => { firebase - ->firestore() + ->firestore ->Firestore.collection("mycollection") ->Firestore.Collection.doc(id) - ->Firestore.Collection.Doc.get() + ->Firestore.Collection.DocRef.get() |> Js.Promise.then_(doc => { - let data = doc->Firestore.DocRef.data(); + let data = doc->Firestore.DocSnapshot.data(); Js.log(data); data; @@ -98,7 +130,7 @@ let fetchItem = (id) => { ```reason let create = (title, description) => firebase - ->firestore() + ->firestore ->Firestore.collection("collection") ->Firestore.Collection.add({ "title": title, @@ -111,12 +143,14 @@ let create = (title, description) => ```reason let update = (id, title) => firebase - ->firestore() + ->firestore ->Firestore.collection("collection") ->Firestore.Collection.doc(id) - ->Firestore.Collection.Doc.set({ - "title": title - }); + ->Firestore.Collection.DocRef.set( + {"title": title}, + ~options=Firestore.Collection.DocRef.setOptions(~merge=true), + (), + ); ``` #### Remove @@ -124,8 +158,8 @@ let update = (id, title) => ```reason let remove = (id: string) => firebase - ->firestore() + ->firestore ->Firestore.collection("mycollection") ->Firestore.Collection.doc(id) - ->Firestore.Collection.Doc.delete(); + ->Firestore.Collection.DocRef.delete(); ``` diff --git a/package.json b/package.json index 5a1ad32..237b59e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dck/bs-firebase", - "version": "0.3.0", + "version": "0.4.0", "scripts": { "build": "bsb -make-world", "start": "bsb -make-world -w", @@ -15,6 +15,6 @@ "author": "Thomas Deconinck", "license": "MIT", "devDependencies": { - "bs-platform": "7.2.1" + "bs-platform": "^7.3.2" } } diff --git a/src/BsFirebase.re b/src/BsFirebase.re index c04a925..4274810 100644 --- a/src/BsFirebase.re +++ b/src/BsFirebase.re @@ -4,10 +4,10 @@ type firebaseConfig; module Auth = BsFirebase__Auth; module Firestore = BsFirebase__Firestore; -[@bs.module] external firebase: firebase = "firebase"; +[@bs.module] external firebase: firebase = "firebase/app"; [@bs.send] external initializeApp: (firebase, firebaseConfig) => unit = "initializeApp"; -[@bs.send] external auth: (firebase, unit) => Auth.t = "auth"; -[@bs.send] external firestore: (firebase, unit) => Firestore.t = "firestore"; \ No newline at end of file +[@bs.send] external auth: firebase => Auth.t = "auth"; +[@bs.send] external firestore: firebase => Firestore.t = "firestore"; \ No newline at end of file diff --git a/src/BsFirebase.rei b/src/BsFirebase.rei index c04a925..4274810 100644 --- a/src/BsFirebase.rei +++ b/src/BsFirebase.rei @@ -4,10 +4,10 @@ type firebaseConfig; module Auth = BsFirebase__Auth; module Firestore = BsFirebase__Firestore; -[@bs.module] external firebase: firebase = "firebase"; +[@bs.module] external firebase: firebase = "firebase/app"; [@bs.send] external initializeApp: (firebase, firebaseConfig) => unit = "initializeApp"; -[@bs.send] external auth: (firebase, unit) => Auth.t = "auth"; -[@bs.send] external firestore: (firebase, unit) => Firestore.t = "firestore"; \ No newline at end of file +[@bs.send] external auth: firebase => Auth.t = "auth"; +[@bs.send] external firestore: firebase => Firestore.t = "firestore"; \ No newline at end of file diff --git a/src/BsFirebase__Auth.re b/src/BsFirebase__Auth.re index 5604fa2..3761ff8 100644 --- a/src/BsFirebase__Auth.re +++ b/src/BsFirebase__Auth.re @@ -1,5 +1,7 @@ type t; +[@bs.module] external require: t = "firebase/auth"; + module User = { type t; @@ -11,6 +13,9 @@ module User = { [@bs.get] external refreshToken: t => string = "refreshToken"; [@bs.get] external uid: t => string = "uid"; [@bs.get] external phoneNumber: t => Js.Nullable.t(string) = "phoneNumber"; + + [@bs.send] + external getIdToken: (t, unit) => Js.Promise.t(string) = "getIdToken"; }; module Result = { @@ -65,11 +70,30 @@ module Provider = { external twitter: unit => t = "TwitterAuthProvider"; }; +[@bs.send] +external signInAnonymously: t => Js.Promise.t(Result.t) = "signInAnonymously"; + [@bs.send] external signInWithEmailAndPassword: (t, ~email: string, ~password: string) => Js.Promise.t(Result.t) = "signInWithEmailAndPassword"; +type actionCodeSettings = {url: string}; +[@bs.send] +external sendPasswordResetEmail: + ( + t, + ~email: string, + ~actionCodeSettings: Js.Nullable.t(actionCodeSettings) + ) => + Js.Promise.t(unit) = + "sendPasswordResetEmail"; + +[@bs.send] +external confirmPasswordReset: + (t, ~code: string, ~newPassword: string) => Js.Promise.t(unit) = + "confirmPasswordReset"; + [@bs.send] external signInWithPopup: (t, Provider.t) => Js.Promise.t(Result.t) = "signInWithPopup"; @@ -78,4 +102,6 @@ external signInWithPopup: (t, Provider.t) => Js.Promise.t(Result.t) = external onAuthStateChanged: (t, Js.Nullable.t(User.t) => unit) => unit = "onAuthStateChanged"; -[@bs.send] external signOut: (t, unit) => unit = "signOut"; \ No newline at end of file +[@bs.send] external signOut: (t, unit) => unit = "signOut"; + +[@bs.get] external currentUser: t => User.t = "currentUser"; \ No newline at end of file diff --git a/src/BsFirebase__Firestore.re b/src/BsFirebase__Firestore.re index 5a9b2a0..610f881 100644 --- a/src/BsFirebase__Firestore.re +++ b/src/BsFirebase__Firestore.re @@ -1,6 +1,6 @@ type t; -module DocRef = { +module DocSnapshot = { type t; [@bs.get] external exists: t => bool = "exists"; @@ -11,28 +11,29 @@ module DocRef = { module QuerySnapshot = { type t; - [@bs.get] external docs: t => array(DocRef.t) = "docs"; + [@bs.get] external docs: t => array(DocSnapshot.t) = "docs"; + [@bs.get] external size: t => int = "size"; }; module Collection = { type t; - module Doc = { + module DocRef = { type t; [@bs.deriving abstract] type setOptions = {merge: bool}; - [@bs.send] external get: (t, unit) => Js.Promise.t(DocRef.t) = "get"; + [@bs.send] external get: (t, unit) => Js.Promise.t(DocSnapshot.t) = "get"; [@bs.send] external delete: (t, unit) => Js.Promise.t(unit) = "delete"; [@bs.send] - external set: (t, 'a, ~options: setOptions=?) => Js.Promise.t(unit) = + external set: (t, 'a, ~options: setOptions=?, unit) => Js.Promise.t(unit) = "set"; }; [@bs.send] external add: (t, 'a) => Js.Promise.t(DocRef.t) = "add"; [@bs.send] external get: (t, unit) => Js.Promise.t(QuerySnapshot.t) = "get"; - [@bs.send] external doc: (t, string) => Doc.t = "doc"; + [@bs.send] external doc: (t, string) => DocRef.t = "doc"; [@bs.send] external where: ( @@ -54,4 +55,19 @@ module Collection = { [@bs.module] external require: t = "firebase/firestore"; -[@bs.send] external collection: (t, string) => Collection.t = "collection"; \ No newline at end of file +[@bs.send] external collection: (t, string) => Collection.t = "collection"; + +module Transaction = { + type firestore = t; + type t; + + type updateFunction('a) = t => Js.Promise.t('a); + + [@bs.send] external get: (t, Collection.DocRef.t) => Js.Promise.t(DocSnapshot.t) = "get"; + [@bs.send] external update: (t, Collection.DocRef.t, 'a) => t = "update"; + [@bs.send] external set: (t, Collection.DocRef.t, 'a, ~options: Collection.DocRef.setOptions=?, unit) => t = "set"; + [@bs.send] external delete: (t, Collection.DocRef.t) => t = "delete"; +} + + +[@bs.send] external runTransaction: (t, Transaction.updateFunction('a)) => Js.Promise.t('a) = "runTransaction"; \ No newline at end of file