diff --git a/README.md b/README.md
index f38c055..2a79a83 100755
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
# framer-Firebase
The **Firebase module** allows your Framer prototype to **load**, **save** and **sync** data effortlessly between multiple sessions and devices.
+
+Updated to support Promises.
## Demo Projects
@@ -27,8 +29,8 @@ These examples include access to a public demo database for the purpose of demon
## Getting started in under 5 minutes
-
+
OR
@@ -108,8 +110,8 @@ The required information is located at https://firebase.google.com → *Console*
```coffee
firebase = new Firebase
- projectID: ___________ # 1) ... Database → first part of URL
- secret: ______________ # 2) ... Project Settings → Service Accounts → Database Secrets → Show (mouse-over)
+ projectID: ___________ # 1) ... Database → first part of URL
+ secret: ______________ # 2) ... Project Settings → Service Accounts → Database Secrets → Show (mouse-over)
```
@@ -134,8 +136,8 @@ If you wish not to use and share your database *secret* in your Framer project l
```json
{
"rules": {
- ".read": "true",
- ".write": "true"
+ ".read": "true",
+ ".write": "true"
}
}
```
@@ -196,20 +198,34 @@ Retrieves data from the database.
```coffee
# Simple 1, expecting single value
firebase.get "/value", (value) ->
- print value
+ print value
+
+# Promise
+firebase.get "/value"
+.then (value) -> print value
# Simple 2, expecting dataset
firebase.get "/names", (names) ->
- namesArray = _.toArray(names) # converts JSON to array
- print name for name in namesArray
+ namesArray = _.toArray(names) # converts JSON to array
+ print name for name in namesArray
+
+# Promise
+firebase.get "/names"
+.then (names) ->
+ namesArray = _.toArray(names) # converts JSON to array
+ print name for name in namesArray
# Advanced
response = (names) ->
- namesArray = _.toArray(names)
- print name for name in namesArray
+ namesArray = _.toArray(names)
+ print name for name in namesArray
firebase.get("/names",response,{orderBy: "$key", limitToFirst: 5})
+# Promise
+firebase.get("/names",{orderBy: "$key", limitToFirst: 5})
+.then(response)
+
```
@@ -232,10 +248,13 @@ firebase.put("/value", true)
# Advanced
response = (confirmation) ->
- print confirmation
+ print confirmation
firebase.put("/values", {"foo": true, "bar": false}, response)
+# Promise
+firebase.put("/values", {"foo": true, "bar": false})
+.then(response)
```
@@ -258,19 +277,19 @@ firebase.post("/value", true)
# Advanced
firebase.post("/addressBook", { # JSON encoded:
- "name" : {
- "forename" : "Jane",
- "surename" : "Doe"
- }
+ "name" : {
+ "forename" : "Jane",
+ "surename" : "Doe"
+ }
- "birthday" : {
- "day" : 4,
- "month": 7,
- "year" : 1976
- }
+ "birthday" : {
+ "day" : 4,
+ "month": 7,
+ "year" : 1976
+ }
- "tel" : "202-555-0101"
- })
+ "tel" : "202-555-0101"
+ })
```
@@ -313,14 +332,14 @@ Fires, when the Framer project is loaded (returns all current data of the path)
# Simple
firebase.onChange "/values", (value) ->
- print value
+ print value
# Advanced
response = (data, method, path, breadcrumbs) ->
- # method returns either `put´ or `patch´, depending on what method changed the data
- # path returns the path that was changed
- # breadcrumbs returns the path as segments (array)
- print "received #{data} via #{method}"
+ # method returns either `put´ or `patch´, depending on what method changed the data
+ # path returns the path that was changed
+ # breadcrumbs returns the path as segments (array)
+ print "received #{data} via #{method}"
firebase.onChange("/values", response)
@@ -336,8 +355,8 @@ Fires, whenever the connection status to Firebase has changed.
```coffee
firebase.onChange "connection", (status) ->
- # status is either `connected´ or `disconnected´
- print "Hooray, we're connected to Firebase" if status is "connected"
+ # status is either `connected´ or `disconnected´
+ print "Hooray, we're connected to Firebase" if status is "connected"
# Or
@@ -376,11 +395,11 @@ For further information on how to order or limit requests please refer to [Fireb
```JSON
{
- "rules": {
- ".read": "auth != null",
- ".write": "auth != null",
- "routes": {".indexOn": ["distance"]}
- }
+ "rules": {
+ ".read": "auth != null",
+ ".write": "auth != null",
+ "routes": {".indexOn": ["distance"]}
+ }
}
```
diff --git a/firebase.coffee b/firebase.coffee
index b46ea64..e5dd3a3 100644
--- a/firebase.coffee
+++ b/firebase.coffee
@@ -1,5 +1,3 @@
-
-
# Documentation of this Module: https://github.com/marckrenn/framer-Firebase
# ------ : ------- Firebase REST API: https://firebase.google.com/docs/reference/rest/database/
@@ -23,13 +21,11 @@ class exports.Firebase extends Framer.BaseClass
console.log "Firebase: Connecting to Firebase Project '#{@projectID}' ... \n URL: 'https://#{@projectID}.firebaseio.com'" if @debug
@.onChange "connection"
-
request = (project, secret, path, callback, method, data, parameters, debug) ->
url = "https://#{project}.firebaseio.com#{path}.json#{secret}"
-
- unless parameters is undefined
+ if parameters?
if parameters.shallow then url += "&shallow=true"
if parameters.format is "export" then url += "&format=export"
@@ -47,45 +43,40 @@ class exports.Firebase extends Framer.BaseClass
url += "&startAt=#{parameters.startAt}" if typeof parameters.startAt is "number"
url += "&endAt=#{parameters.endAt}" if typeof parameters.endAt is "number"
url += "&equalTo=#{parameters.equalTo}" if typeof parameters.equalTo is "number"
-
- xhttp = new XMLHttpRequest
+
console.log "Firebase: New '#{method}'-request with data: '#{JSON.stringify(data)}' \n URL: '#{url}'" if debug
- xhttp.onreadystatechange = =>
-
- unless parameters is undefined
- if parameters.print is "silent" or typeof parameters.download is "string" then return # ugh
-
- switch xhttp.readyState
- when 0 then console.log "Firebase: Request not initialized \n URL: '#{url}'" if debug
- when 1 then console.log "Firebase: Server connection established \n URL: '#{url}'" if debug
- when 2 then console.log "Firebase: Request received \n URL: '#{url}'" if debug
- when 3 then console.log "Firebase: Processing request \n URL: '#{url}'" if debug
- when 4
- if xhttp.responseText?
- callback(JSON.parse(xhttp.responseText)) if callback?
- console.log "Firebase: Request finished, response: '#{JSON.parse(xhttp.responseText)}' \n URL: '#{url}'" if debug
- else
- console.log "Lost connection to Firebase." if debug
-
-
- if xhttp.status is "404"
- console.warn "Firebase: Invalid request, page not found \n URL: '#{url}'" if debug
-
-
- xhttp.open(method, url, true)
- xhttp.setRequestHeader("Content-type", "application/json; charset=utf-8")
- xhttp.send(data = "#{JSON.stringify(data)}")
-
-
+
+ options = if data?
+ body: JSON.stringify(data)
+ method: method
+ headers:
+ 'content-type': 'application/json; charset=utf-8'
+
+ r = fetch url, (options ? {})
+ .then (res) ->
+ if !res.ok then throw Error(res.statusText)
+ json = res.json()
+ json.then callback
+ return json
+ .catch (error) => console.warn(error)
+
+ return r
+
+ # Third argument can also accept options, rather than callback
+ parseArgs = (l, args..., cb) ->
+ if typeof args[l-1] is "object"
+ args[l] = args[l-1]
+ args[l-1] = null
+
+ return cb.apply(null, args)
# Available methods
- get: (path, callback, parameters) -> request(@projectID, @secretEndPoint, path, callback, "GET", null, parameters, @debug)
- put: (path, data, callback, parameters) -> request(@projectID, @secretEndPoint, path, callback, "PUT", data, parameters, @debug)
- post: (path, data, callback, parameters) -> request(@projectID, @secretEndPoint, path, callback, "POST", data, parameters, @debug)
- patch: (path, data, callback, parameters) -> request(@projectID, @secretEndPoint, path, callback, "PATCH", data, parameters, @debug)
- delete: (path, callback, parameters) -> request(@projectID, @secretEndPoint, path, callback, "DELETE", null, parameters, @debug)
-
+ get: (args...) -> parseArgs 2, args..., (path, callback, parameters) => request(@projectID, @secretEndPoint, path, callback, "GET", null, parameters, @debug)
+ put: (args...) -> parseArgs 3, args..., (path, data, callback, parameters) => request(@projectID, @secretEndPoint, path, callback, "PUT", data, parameters, @debug)
+ post: (args...) -> parseArgs 3, args..., (path, data, callback, parameters) => request(@projectID, @secretEndPoint, path, callback, "POST", data, parameters, @debug)
+ patch: (args...) -> parseArgs 3, args..., (path, data, callback, parameters) => request(@projectID, @secretEndPoint, path, callback, "PATCH", data, parameters, @debug)
+ delete: (args...) -> parseArgs 2, args..., (path, callback, parameters) => request(@projectID, @secretEndPoint, path, callback, "DELETE", null, parameters, @debug)
onChange: (path, callback) ->
@@ -111,17 +102,16 @@ class exports.Firebase extends Framer.BaseClass
console.warn "Firebase: Connection to Firebase Project '#{@projectID}' closed" if @debug
currentStatus = "disconnected"
+ return
- else
-
- url = "https://#{@projectID}.firebaseio.com#{path}.json#{@secretEndPoint}"
- source = new EventSource(url)
- console.log "Firebase: Listening to changes made to '#{path}' \n URL: '#{url}'" if @debug
+ url = "https://#{@projectID}.firebaseio.com#{path}.json#{@secretEndPoint}"
+ source = new EventSource(url)
+ console.log "Firebase: Listening to changes made to '#{path}' \n URL: '#{url}'" if @debug
- source.addEventListener "put", (ev) =>
- callback(JSON.parse(ev.data).data, "put", JSON.parse(ev.data).path, _.tail(JSON.parse(ev.data).path.split("/"),1)) if callback?
- console.log "Firebase: Received changes made to '#{path}' via 'PUT': #{JSON.parse(ev.data).data} \n URL: '#{url}'" if @debug
+ source.addEventListener "put", (ev) =>
+ callback(JSON.parse(ev.data).data, "put", JSON.parse(ev.data).path, _.tail(JSON.parse(ev.data).path.split("/"),1)) if callback?
+ console.log "Firebase: Received changes made to '#{path}' via 'PUT': #{JSON.parse(ev.data).data} \n URL: '#{url}'" if @debug
- source.addEventListener "patch", (ev) =>
- callback(JSON.parse(ev.data).data, "patch", JSON.parse(ev.data).path, _.tail(JSON.parse(ev.data).path.split("/"),1)) if callback?
- console.log "Firebase: Received changes made to '#{path}' via 'PATCH': #{JSON.parse(ev.data).data} \n URL: '#{url}'" if @debug
+ source.addEventListener "patch", (ev) =>
+ callback(JSON.parse(ev.data).data, "patch", JSON.parse(ev.data).path, _.tail(JSON.parse(ev.data).path.split("/"),1)) if callback?
+ console.log "Firebase: Received changes made to '#{path}' via 'PATCH': #{JSON.parse(ev.data).data} \n URL: '#{url}'" if @debug