The Firebase module allows your Framer prototype to load, save and sync data effortlessly between multiple sessions and devices.
Updated to support Promises.
Simple | Advanced |
---|---|
Loads, saves and syncs slider.value w/ 2 lines of code | World's first(?) bubble popping MMO |
Live @ firebaseSlider | Live @ firebaseBubbles |
Placeholder | Advanced |
---|---|
Like-counts, three of them | |
Live @ firebaseLikes |
These examples include access to a public demo database for the purpose of demonstration.
Please DON'T use this demo database for your projects! Your data will be deleted.
OR
Step | Instruction |
---|---|
1 | Download the Firebase module and unzip the downloaded archive |
2 | Put firebase.coffee into your prototype's modules -folder or drag'n'drop it onto the Framer window |
3 | Add or change the autogenerated require -line to {Firebase} = require 'firebase' |
4 | Reload (CMD+R) or save (CMD+S) your project to get Framer to load the module |
-!- | Or start by using this template file |
5 | Go to https://firebase.google.com → Login → Console → Create New Project |
6 | Back in Framer, add firebase = new Firebase and set the required Class Properties |
7 | Save, load and sync data using the available Class Methods. Also, check out the Demo Projects. |
I'd also like to recommend reading Supercharge your Framer prototype with Firebase, pt.1 on Medium, if you haven't already.
Tip | |
---|---|
1 | You can use a single database to store data for multiple Framer prototypes. |
2 | Use https://firebase.google.com → Console → YourProject → Database to see realtimes changes made to your database. This will give you a better understanding of how Firebase methods alter your data. |
3 | Framer's Auto Refresh can cause some unwanted behavior in combination with this module, hence why I'd suggest turning it off and to reload manually (CMD+R). |
4 | Anti-Virus software like Avast seem to interfere with the .onChange()-method, as it looks like a potential Cross-Site-Scripting-attack. This will hopefully be fixed soon by the Firebase team. |
5 | Try to limit put- / post- / patch- serverrequests to a reasnobable refresh rate (either by syncing at the end of interaction or by using Utils.debounce). Data flooding can cause severe lags. |
Data on Firebase is stored as JSON, the supported data types are: Number, String, Boolean, Array, Object and Null. For more information on JSON data types, please refer to the JSON article on Wikipedia.org.
The database used for the provided Demo Projects looks something like this:
If you need further assistance or want to leave me some feedback,
you can reach me via Twitter, Facebook or Slack.
--- ---
This module is based on Firebase's REST API.
Table of contents |
---|
1) Properties |
|--- firebase.projectID, .secret |
|--- firebase.secret |
|--- firebase.debug |
|--- firebase.status |
2) Methods |
|--- firebase.get() |
|--- firebase.put() |
|--- firebase.post() |
|--- firebase.patch() |
|--- firebase.delete() |
|--- firebase.onChange() |
3) Parameters |
|--- OrderBy- and Limit-parameters |
The property projectID is required for the module to work.
secret is now an optional property and it can be either set (see below) or it can be substitued by changing your database access rules.
The required information is located at https://firebase.google.com → Console → YourProject → ...
firebase = new Firebase
projectID: ___________ # 1) ... Database → first part of URL
secret: ______________ # 2) ... Project Settings → Service Accounts → Database Secrets → Show (mouse-over)
1) projectID | 2) secret |
---|---|
Protip: Contrary to what I did in the gif, I advise you NOT to share your Firebase secret publicly, as it allow others to alter the data stored in your database. If you do so by accident, you can always revoke access by deleting the shared secret and creating a new one at https://firebase.google.com → Console → Project Settings → Service Accounts → Database Secrets.
Optional: If you wish not to use and share your database secret in your Framer project like shown above, you can do the following instead:
Steps | |
---|---|
1 | Go to Console → YourProject → Database → RULES |
2 | Change the rules of .read and .write to true like this: |
{
"rules": {
".read": "true",
".write": "true"
}
}
Step | |
---|---|
3 | If you've already set the secret-property before, you can remove it as it's no longer needed. |
Caution: Similar to sharing your database secret key publicly, this will grant everyone on the web with write-access, which will allow everyone to read and modify data saved in your database! Please only share your projects (and Firebase projectIDs) with people you trust.
If set to true, relevant connection messages will be logged to the console.
Returns the current connection status, either "connected" or "disconnected".
Overview
Method | Arguments | Use case |
---|---|---|
firebase.get | (path, callback, parameters) | Retreives data |
firebase.put | (path, data, callback, parameters) | Writes / updates data |
firebase.post | (path, data, callback, parameters) | Writes data using a random key |
firebase.patch | (path, data, callback, parameters) | Updates data |
firebase.delete | (path, callback, parameters) | Deletes data |
firebase.onChange | (path or "connection", callback) | Monitors / syncs data |
Protip: As a beginner, you can ignore separated callback-functions and parameters.
Note | |
---|---|
1 | Sent and received data is either plain (single value) or JSON encoded (dataset) |
2 | The use of the parameters-argument requires a callback-function to be set |
3 | The otherwise optional callback-function always returns a server response confirming the request |
4 | Multiple paramters can be set by using curly braces (eg. firebase.get("/values", callback, {parameter1: true, parameter2: 3}) ) |
Retrieves data from the database.
Examples:
# Simple 1, expecting single value
firebase.get "/value", (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
# 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
firebase.get("/names",response,{orderBy: "$key", limitToFirst: 5})
# Promise
firebase.get("/names",{orderBy: "$key", limitToFirst: 5})
.then(response)
Writes data to the database.
If the path does not exist, it will be created, if it does exist, the specified node will be updated with the new data.
The following data types are supported: Number, String, Boolean, Array, Object and Null.
For more information on JSON data types, please refer to the JSON article on Wikipedia.org.
Tip: To update data without deleting omitted children- or sibling-nodes, use firebase.patch() instead.
Examples:
# Simple
firebase.put("/value", true)
# Advanced
response = (confirmation) ->
print confirmation
firebase.put("/values", {"foo": true, "bar": false}, response)
# Promise
firebase.put("/values", {"foo": true, "bar": false})
.then(response)
Adds data to the specified path using a random key (eg. "/addressBook/-KIU9s3bWOpODk9cai_n/"
).
This is useful when adding new data to a node (eg. adding a new entry to an address book). The random key also prevents possible data interference between multiple, concurrent users.
The following data types are supported: Number, String, Boolean, Array, Object and Null.
For more information on JSON data types, please refer to the JSON article on Wikipedia.org.
Examples:
# Simple
firebase.post("/value", true)
# Advanced
firebase.post("/addressBook", { # JSON encoded:
"name" : {
"forename" : "Jane",
"surename" : "Doe"
}
"birthday" : {
"day" : 4,
"month": 7,
"year" : 1976
}
"tel" : "202-555-0101"
})
Updates data of the specified path, without deleting omitted sibling-nodes.
Example:
firebase.patch("/values/foo", false) # `/values/bar´ persists
Deletes the node and children of the specified path.
Example:
firebase.delete("/values")
Monitoring a database path:
Fires, when the Framer project is loaded (returns all current data of the path) and whenever some of its data was changed (returns only the newly added or changed data), across multiple devices or browser windows. If it returns null, the node has been deleted.
Example:
# Simple
firebase.onChange "/values", (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}"
firebase.onChange("/values", response)
Monitoring the connection status:
First argument must be set to "connection".
Fires, whenever the connection status to Firebase has changed.
Example:
firebase.onChange "connection", (status) ->
# status is either `connected´ or `disconnected´
print "Hooray, we're connected to Firebase" if status is "connected"
# Or
firebase.onChange "connection" -> print "Current connection status: #{firebase.status}"
Available parameters:
Parameter | Value | Type | Compatible w/ | Description |
---|---|---|---|---|
shallow: | true | Boolean | .get() | Returns the data of the specified node without its children. Note: Shallow cannot be mixed with any other parameters |
print: | "pretty" | String | .get(), .put(), .post(), .patch(), .delete() | Returns the data in a human-readable format |
print: | "silent" | String | .get(), .put(), .post(), .patch() | Surpresses response from the Firebase server, virtually identical to not setting a callback function |
format: | "export" | String | .get() | Include priority information in the response |
download: | path | String | .get() | Will trigger a download if pointed to a file stored on the Firebase server (YourProject → Console → Storage) |
For further information on how to order or limit requests please refer to Firebase REST Guide / Retriving data.
Parameter | Type | Description |
---|---|---|
orderBy: | String | "$key" requires an index to be set at Console → Database → Rules. See example below. |
Indexing example:
{
"rules": {
".read": "auth != null",
".write": "auth != null",
"routes": {".indexOn": ["distance"]}
}
}
Note: Limit-parameters require the orderBy-parameter to be set.
Parameter | Type |
---|---|
limitToFirst: | Number |
limitToLast: | Number |
startAt: | Number |
endAt: | Number |
equalTo: | Number |