/exfirebase

An elixir library for accessing the Firebase REST API.

Primary LanguageElixir

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.