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
Hello!
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) |>
parse_firestore_to_model()
end
def sync_scores(conn, server, scores) do
body = scores |>
package_to_firestore_types
{:ok, _response} = GoogleApi.Firestore.V1.Api.Projects.firestore_projects_databases_documents_patch(conn, @firestore_url <> server, updateMask: @updateMask, body: body)
:ok
end
defp package_to_firestore_types(scores) do
scores = Enum.map(scores, &to_firestore_score/1)
%{
fields: %{"highscores" =>
%GoogleApi.Firestore.V1.Model.Value{
arrayValue: %GoogleApi.Firestore.V1.Model.ArrayValue{values: scores}
}
}
}
end
defp to_firestore_score(%Highscores.Model.Score{name: name, rank: rank, score: score}) do
%GoogleApi.Firestore.V1.Model.Value{
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)}
}
}
}
end
defp parse_firestore_to_model(highscores) do
Enum.map(highscores, &parse_score/1)
end
defp parse_score(entry) do
fields = entry |>
Map.get(:mapValue) |>
Map.get(:fields)
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}
end
end
I’ve managed to use the gRPC API to make a simple connection to it: