Skip to content

Commit

Permalink
Merge pull request #8 from steveruizok/master
Browse files Browse the repository at this point in the history
Promises!
  • Loading branch information
marckrenn authored Apr 21, 2018
2 parents 4a07194 + 7273b9f commit 2b46f4f
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 86 deletions.
89 changes: 54 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
<br />

## Demo Projects
Expand All @@ -27,8 +29,8 @@ These examples include access to a public demo database for the purpose of demon
## Getting started in under 5 minutes

<a href='https://open.framermodules.com/Firebase'>
<img alt='Install with Framer Modules'
src='https://www.framermodules.com/assets/[email protected]' width='160' height='40' /></a>
<img alt='Install with Framer Modules'
src='https://www.framermodules.com/assets/[email protected]' width='160' height='40' /></a>

<strong>OR</strong>

Expand Down Expand Up @@ -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)
```


Expand All @@ -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"
}
}
```
Expand Down Expand Up @@ -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)

```
<br />

Expand All @@ -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)
```
<br />

Expand All @@ -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"
})

```
<br />
Expand Down Expand Up @@ -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)

Expand All @@ -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

Expand Down Expand Up @@ -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"]}
}
}

```
Expand Down
92 changes: 41 additions & 51 deletions firebase.coffee
Original file line number Diff line number Diff line change
@@ -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/

Expand All @@ -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"

Expand All @@ -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) ->
Expand All @@ -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

0 comments on commit 2b46f4f

Please sign in to comment.