An elixir library for accessing the Firebase REST API.
Elixir Shell
Switch branches/tags

README.md

ExFirebase Build Status Coverage Status

An elixir library for accessing the Firebase REST API.

Detail of the API is described in https://www.firebase.com/docs/rest-api.html

Prerequisite

Signing up Firebase and getting the access url (https://xxx.firebaseio.com/) is required.

Sample

defmodule Sample do
  def test do
    # acquire your Firebase URL (https://xxx.firebaseio.com/) from the environment variable.
    url = System.get_env("FIREBASE_URL")

    # setup url for ExFirebase module
    ExFirebase.set_url(url)

    # put data in /test path"
    ExFirebase.put("test", ["abc", "def"])

    # get data in /test path" and print
    IO.inspect ExFirebase.get("test")  # -> ["abc", "def"]
  end
end

Sample.test
# ["abc", "def"]

Running sample.ex

run_sample.sh calls the sample.ex.

Clone the repository

$ git clone git://github.com/parroty/exfirebase.git

Set environment variable for the script

$ export FIREBASE_URL="your firebase url"

Run the script

$ ./run_sample.sh
["abc", "def"]

Running on iex

Specify environment variables in advance.

$ export FIREBASE_URL="your firebase url"

Then run the "run_iex.sh". It loads up "dot.iex" and related libraries. It has pre-defined alias variables (fb) for API operations.

$ ./run_iex.sh
iex(1)> fb
ExFirebase
iex(2)> fb.put("iex", [1, 3, 5])
[1, 3, 5]
iex(3)> a = fb.get("iex")
[1, 3, 5]
iex(4)> a = a ++ [7, 9]
[1, 3, 5, 7, 9]
iex(5)> fb.put("iex", a)
[1, 3, 5, 7, 9]
iex(6)> fb.get("iex")
[1, 3, 5, 7, 9]
iex(7)> fb.delete("iex")
[]
iex(8)> fb.get("iex")
[]

Running on Dynamo

The following repo is a sample dynamo project for implementing rails-like scaffold page built using exfirebase.

Usage

raw json

iex(1)> IO.puts fb.get_raw_json("pretty_test")
[{"name":"Jack","id":1},{"name":"John","id":2}]

iex(2)> IO.puts fb.get_raw_json("pretty_test", [pretty: true])
[ {
  "name" : "Jack",
  "id" : 1
}, {
  "name" : "John",
  "id" : 2
} ]

auth token

ex(1)> fb.get("login")
[{"error", "Permission denied."}]
iex(2)> fb.set_auth_token("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
:ok
iex(3)> fb.get("login")
[{"last", "Sparrow"}, {"first", "Jack"}]

records

iex(1)> defmodule Test do
...(1)>   defstruct id: nil, name: nil
...(1)> end
{:module, Test,
 <<70, 79, 82, 49, 0, 0, 4, 204, 66, 69, 65, 77, 65, 116, 111, 109, 0, 0, 0, 110, 0, 0, 0, 11, 11, 69, 108, 105, 120, 105, 114, 46, 84, 101, 115, 116, 8, 95, 95, 105, 110, 102, 111, 95, 95, 4, 100, 111, 99, 115, ...>>,
 [id: nil, name: nil]}

iex(2)> rec = [%Test{id: 1, name: "Jack"}, %Test{id: 2, name: "John"}]
[%Test{id: 1, name: "Jack"}, %Test{id: 2, name: "John"}]

iex(3)> ExFirebase.Records.put("record", rec)
[%{"id" => 1, "name" => "Jack"}, %{"id" => 2, "name" => "John"}]

iex(4)> ExFirebase.Records.get("record", Test)
[%Test{id: 1, name: "Jack"}, %Test{id: 2, name: "John"}]

iex(5)> IO.puts ExFirebase.get_raw_json("record", [pretty: true])
[ {
  "name" : "Jack",
  "id" : 1
}, {
  "name" : "John",
  "id" : 2
} ]

dicts

ExFirebase.Dict provides a dictionary operation based on the Firebase-assigned name parameter.

iex(1)> alias ExFirebase.Dict
nil

iex(2)> Dict.post("object", [1,2,3])
{"-J4ARC-BzalPwVIbMY9-", [1, 2, 3]}

iex(3)> Dict.post("object", [4,5,6])
{"-J4ARDLsZplq-ZNlFhgD", [4, 5, 6]}

iex(4)> Dict.get("object")
#HashDict<[{"-J4ARC-BzalPwVIbMY9-", [1, 2, 3]},
 {"-J4ARDLsZplq-ZNlFhgD", [4, 5, 6]}]>

ExFirebase.Dict.Records uses the name parameter as "id" field of the record.

iex(1)>
iex(1)> defmodule Weather do
...(1)>   defstruct id: "", city: "", temp_lo: 0, temp_hi: 0
...(1)> end
{:module, Weather,
 <<70, 79, 82, 49, 0, 0, 5, 0, 66, 69, 65, 77, 65, 116, 111, 109, 0, 0, 0, 113, 0, 0, 0, 11, 14, 69, 108, 105, 120, 105, 114, 46, 87, 101, 97, 116, 104, 101, 114, 8, 95, 95, 105, 110, 102, 111, 95, 95, 4, 100, ...>>,
 [id: "", city: "", temp_lo: 0, temp_hi: 0]}

iex(2)> alias ExFirebase.Dict.Records
nil

iex(3)> use ExFirebase.Dict.Records
nil

iex(4)> Records.post("dict", %Weather{city: "Tokyo"})
%Weather{city: "Tokyo", id: "-JOMPMelEyQUsdDCnZBj", temp_hi: 0, temp_lo: 0}

iex(5)> Records.post("dict", %Weather{city: "Osaka"})
%Weather{city: "Osaka", id: "-JOMPdn8czXNQPiUWWqq", temp_hi: 0, temp_lo: 0}

iex(6)> Records.get("dict", Weather)
%Weather{city: "Tokyo", id: "-JOMVZwI9zFE4xHBuew2", temp_hi: 0, temp_lo: 0},
 %Weather{city: "Osaka", id: "-JOMV_7ePOHc9eTiqNSO", temp_hi: 0, temp_lo: 0}]

iex(7)> record = Records.get("dict", "-JOMVZwI9zFE4xHBuew2", Weather)
%Weather{city: "Tokyo", id: "-JOMVZwI9zFE4xHBuew2", temp_hi: 0, temp_lo: 0}

iex(8)> record = %{record | temp_lo: 10}
%Weather{city: "Tokyo", id: "-JOMVZwI9zFE4xHBuew2", temp_hi: 0, temp_lo: 10}

iex(9)> Records.patch("dict", record)
%Weather{city: "Tokyo", id: "-JOMVZwI9zFE4xHBuew2", temp_hi: 0, temp_lo: 10}

iex(10)> Records.get("dict", "-JOMVZwI9zFE4xHBuew2", Weather)
Weather[id: "-J4AFJDF2A2cEtJRMhgm", city: "Osaka", temp_lo: 10, temp_hi: 0,  prcp: 0]

iex(11)> Records.delete("dict", record)
[]

iex(12)> Records.get("dict",  Weather)
[%Weather{city: "Osaka", id: "-JOMV_7ePOHc9eTiqNSO", temp_hi: 0, temp_lo: 0}]

TODO

  • Support push notification using websocket.
  • Support priority attribute.