Anyone Access firestore from elixir successfully?

I haven’t seen any examples online, fiddled with the Gcp generated client but had no luck.

Ended up getting the rest api to work decently


Do you have an example of this implementation. I would like to use a client or ecto adapter for firestore in my service. Thanks!

An adapter for Ecto would be sweet - let me see if I can put the code up in a gist.

1 Like

Hi @LukeWood, is it possible to see a code example of your implementation of the firestore REST API ? I want to try and upload a document to a collection. Thanks.

I switched to use GoogleApi.Firestore.V1

Some of this code is pretty bad but I don’t actually use it anywhere anymore

defmodule Highscores.Firestore do
  @firestore_url "projects/${PROJECTS}/databases/(default)/documents/highscores/"
  @updateMask %GoogleApi.Firestore.V1.Model.DocumentMask{fieldPaths: ["highscores"]}

  def load_scores(_, nil), do: raise "missing config value: server_name. configure highscores\nconfig :highscores,\n server_name: \"name\""
  def load_scores(conn, server) do
    {:ok, result} = GoogleApi.Firestore.V1.Api.Projects.firestore_projects_databases_documents_get(conn, @firestore_url <> server)
    Map.get(result, :fields) |>
      Map.get("highscores") |>
      Map.get(:arrayValue) |>
      Map.get(:values) |>

  def sync_scores(conn, server, scores) do
    body = scores |>

    {:ok, _response} = GoogleApi.Firestore.V1.Api.Projects.firestore_projects_databases_documents_patch(conn, @firestore_url <> server, updateMask: @updateMask, body: body)

  defp package_to_firestore_types(scores) do
    scores =, &to_firestore_score/1)
      fields: %{"highscores" =>
          arrayValue: %GoogleApi.Firestore.V1.Model.ArrayValue{values: scores}

  defp to_firestore_score(%Highscores.Model.Score{name: name, rank: rank, score: score}) do
      mapValue: %GoogleApi.Firestore.V1.Model.MapValue{
        fields: %{
          "name" =>%GoogleApi.Firestore.V1.Model.Value{stringValue: name},
          "score" =>%GoogleApi.Firestore.V1.Model.Value{integerValue: Integer.to_string(score)},
          "rank" =>%GoogleApi.Firestore.V1.Model.Value{integerValue: Integer.to_string(rank)}

  defp parse_firestore_to_model(highscores) do, &parse_score/1)

  defp parse_score(entry) do
    fields = entry |>
      Map.get(:mapValue) |>

    name = Map.get(fields, "name") |> Map.get(:stringValue)
    {rank, ""} = Map.get(fields, "rank") |> Map.get(:integerValue) |> Integer.parse()
    {score, ""} = Map.get(fields, "score") |> Map.get(:integerValue) |> Integer.parse()

    %Highscores.Model.Score{rank: rank, name: name, score: score}


I’ve managed to use the gRPC API to make a simple connection to it: