From 745b0dc4f2825c00bd1dd8172f99cb9f9aa181e5 Mon Sep 17 00:00:00 2001 From: raphael Date: Thu, 30 Dec 2021 13:06:26 +0100 Subject: [PATCH] adds Firebase communication stump - Firebase connection via Pigeon library - sends bump to a single token at the moment - encrypted test is sent as notification message --- .gitignore | 2 ++ config/config.exs | 5 ++++ google-services.json | 39 ++++++++++++++++++++++++++ lib/bump/application.ex | 4 ++- lib/bump/database.ex | 62 +++++++++++++++++++++++++++++++++++++++++ lib/bump/firebase.ex | 14 ++++++++++ lib/bump/messages.ex | 51 ++++++--------------------------- lib/fcm.ex | 4 +++ mix.exs | 5 +++- mix.lock | 7 +++++ 10 files changed, 148 insertions(+), 45 deletions(-) create mode 100644 google-services.json create mode 100644 lib/bump/database.ex create mode 100644 lib/bump/firebase.ex create mode 100644 lib/fcm.ex diff --git a/.gitignore b/.gitignore index b535265..02019db 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ npm-debug.log # secret information /config/*.secret.exs +/secret/* + diff --git a/config/config.exs b/config/config.exs index bccd212..ce5144b 100644 --- a/config/config.exs +++ b/config/config.exs @@ -47,6 +47,11 @@ config :logger, :console, # Use Jason for JSON parsing in Phoenix config :phoenix, :json_library, Jason +config :bump, Bump.FCM, + adapter: Pigeon.FCM, + project_id: "bump-ce0f4", + service_account_json: File.read!("secret/service-account.json") + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{config_env()}.exs" diff --git a/google-services.json b/google-services.json new file mode 100644 index 0000000..f08212c --- /dev/null +++ b/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "613845155515", + "project_id": "bump-ce0f4", + "storage_bucket": "bump-ce0f4.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:613845155515:android:93e5c4b67c8f8104de739e", + "android_client_info": { + "package_name": "com.maenle.bump" + } + }, + "oauth_client": [ + { + "client_id": "613845155515-vdo4q6nfab9tc0nt0ukorduh24unlmo1.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyDMDJChUVMG7TBmSgi5FNECgUICn4jmHZI" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "613845155515-vdo4q6nfab9tc0nt0ukorduh24unlmo1.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/lib/bump/application.ex b/lib/bump/application.ex index bfe5eae..b5684ac 100644 --- a/lib/bump/application.ex +++ b/lib/bump/application.ex @@ -15,15 +15,17 @@ defmodule Bump.Application do # Start the PubSub system {Phoenix.PubSub, name: Bump.PubSub}, # Start the Endpoint (http/https) - BumpWeb.Endpoint + BumpWeb.Endpoint, # Start a worker by calling: Bump.Worker.start_link(arg) # {Bump.Worker, arg} + Bump.FCM ] # See https://hexdocs.pm/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: Bump.Supervisor] Supervisor.start_link(children, opts) + end # Tell Phoenix to update the endpoint configuration diff --git a/lib/bump/database.ex b/lib/bump/database.ex new file mode 100644 index 0000000..89e050a --- /dev/null +++ b/lib/bump/database.ex @@ -0,0 +1,62 @@ +defmodule Bump.Database do + alias Bump.Repo + alias Bump.Messages.Message + import Ecto.Query + + def pop(sender) do + query = from m in "messages", + where: m.sender == ^sender, + order_by: [desc: m.timestamp], + limit: 1, + select: %{id: m.id, data: m.data, timestamp: m.timestamp} + + res = Repo.one(query) + + if not is_nil(res) do + Repo.delete_all(from m in "messages", where: m.id == ^res.id) + %{data: res.data, timestamp: res.timestamp} + else + %{} + end + + end + + def peek(sender) do + query = from m in "messages", + where: m.sender == ^sender, + order_by: [desc: m.timestamp], + limit: 1, + select: %{data: m.data, timestamp: m.timestamp} + Repo.one(query) + end + + def list(sender, minutes) do + + ago = DateTime.utc_now + |> Timex.shift(minutes: -minutes) + |> DateTime.truncate(:second) + + query = from m in "messages", + where: m.sender == ^sender and + m.timestamp >= ^ago, + select: %{data: m.data, timestamp: m.timestamp} + + Repo.all(query) + end + + def clear(sender) do + query = from m in "messages", + where: m.sender == ^sender + + Repo.delete_all(query) + end + + def push(sender, message) do + time = DateTime.utc_now |> DateTime.truncate(:second) + + Repo.insert(%Message{sender: sender, data: message, timestamp: time}) + + end + + +end diff --git a/lib/bump/firebase.ex b/lib/bump/firebase.ex new file mode 100644 index 0000000..076f1ff --- /dev/null +++ b/lib/bump/firebase.ex @@ -0,0 +1,14 @@ +defmodule Bump.Firebase do + + def test() do + IO.puts "Hello, world!" + end + + def push(sender, message) do + IO.puts "Pushing #{message} to #{sender}" + n = Pigeon.FCM.Notification.new({:token, "dTm8S2bfTdKYQTjrxnwFFg:APA91bHGgM7IdRS5uxD0ljmwmP6cAec2icX0VBs69iRB2ApsohyOWzTzontO7cBkjNYbWV87zvxrXIs5jHkJ-8mSWa_-RiU2Y8-XEy3g-Fep3z6dhDeM3KazP58jDRgbdB5cVpDcIEWL"}, %{"body" => message}) + Bump.FCM.push(n) + %{status: 'cheese'} + end + +end diff --git a/lib/bump/messages.ex b/lib/bump/messages.ex index 6cb28f3..a317d4f 100644 --- a/lib/bump/messages.ex +++ b/lib/bump/messages.ex @@ -1,61 +1,26 @@ defmodule Bump.Messages do - alias Bump.Repo - alias Bump.Messages.Message - import Ecto.Query + alias Bump.Database + alias Bump.Firebase def pop(sender) do - query = from m in "messages", - where: m.sender == ^sender, - order_by: [desc: m.timestamp], - limit: 1, - select: %{id: m.id, data: m.data, timestamp: m.timestamp} - - res = Repo.one(query) - - if not is_nil(res) do - Repo.delete_all(from m in "messages", where: m.id == ^res.id) - %{data: res.data, timestamp: res.timestamp} - else - %{} - end - + Database.pop(sender) end def peek(sender) do - query = from m in "messages", - where: m.sender == ^sender, - order_by: [desc: m.timestamp], - limit: 1, - select: %{data: m.data, timestamp: m.timestamp} - Repo.one(query) + Database.peek(sender) end def list(sender, minutes) do - - ago = DateTime.utc_now - |> Timex.shift(minutes: -minutes) - |> DateTime.truncate(:second) - - query = from m in "messages", - where: m.sender == ^sender and - m.timestamp >= ^ago, - select: %{data: m.data, timestamp: m.timestamp} - - Repo.all(query) + Database.list(sender, minutes) end def clear(sender) do - query = from m in "messages", - where: m.sender == ^sender - - Repo.delete_all(query) + Database.clear(sender) end def push(sender, message) do - time = DateTime.utc_now |> DateTime.truncate(:second) - - Repo.insert(%Message{sender: sender, data: message, timestamp: time}) - + Database.push(sender, message) + Firebase.push(sender, message) end diff --git a/lib/fcm.ex b/lib/fcm.ex new file mode 100644 index 0000000..7c761b3 --- /dev/null +++ b/lib/fcm.ex @@ -0,0 +1,4 @@ +# lib/fcm.ex +defmodule Bump.FCM do + use Pigeon.Dispatcher, otp_app: :bump +end diff --git a/mix.exs b/mix.exs index f006786..e44348c 100644 --- a/mix.exs +++ b/mix.exs @@ -49,10 +49,13 @@ defmodule Bump.MixProject do {:timex, "~> 3.0"}, {:gettext, "~> 0.18"}, {:jason, "~> 1.2"}, - {:plug_cowboy, "~> 2.5"} + {:plug_cowboy, "~> 2.5"}, + {:pigeon, "~> 2.0.0-rc.0"}, + {:kadabra, "~> 0.6.0"} ] end + # Aliases are shortcuts or tasks specific to the current project. # For example, to install project dependencies and perform other setup tasks, run: # diff --git a/mix.lock b/mix.lock index d71248d..72dbb4f 100644 --- a/mix.lock +++ b/mix.lock @@ -14,10 +14,16 @@ "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "floki": {:hex, :floki, "0.32.0", "f915dc15258bc997d49be1f5ef7d3992f8834d6f5695270acad17b41f5bcc8e2", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "1c5a91cae1fd8931c26a4826b5e2372c284813904c8bacb468b5de39c7ececbd"}, "gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"}, + "goth": {:hex, :goth, "1.3.0-rc.3", "734a0a381c29df82af33039874aac02ad292199e155a25ad4320872788209dee", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "ab61d5ab6f59a5ea0404d332c9ad3f2463ae4072aabe4f9ef96d624e271254af"}, "hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"}, + "hpack": {:hex, :hpack_erl, "0.2.3", "17670f83ff984ae6cd74b1c456edde906d27ff013740ee4d9efaa4f1bf999633", [:rebar3], [], "hexpm", "06f580167c4b8b8a6429040df36cc93bba6d571faeaec1b28816523379cbb23a"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, + "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, + "joken": {:hex, :joken, "2.4.1", "63a6e47aaf735637879f31babfad93c936d63b8b7d01c5ef44c7f37689e71ab4", [:mix], [{:jose, "~> 1.11.2", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "d4fc7c703112b2dedc4f9ec214856c3a07108c4835f0f174a369521f289c98d1"}, + "jose": {:hex, :jose, "1.11.2", "f4c018ccf4fdce22c71e44d471f15f723cb3efab5d909ab2ba202b5bf35557b3", [:mix, :rebar3], [], "hexpm", "98143fbc48d55f3a18daba82d34fe48959d44538e9697c08f34200fa5f0947d2"}, + "kadabra": {:hex, :kadabra, "0.6.0", "8d8de886802f38d86d2c250eb9416e3208b5e4b78ce8409b40b4d57f21d21fc9", [:mix], [{:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:hpack, "~> 0.2.3", [hex: :hpack_erl, repo: "hexpm", optional: false]}], "hexpm", "0cdaf72fc6205cba62da9e49ee6b24b7c50adb6d9f8b0e92b4b1847959371403"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, @@ -30,6 +36,7 @@ "phoenix_live_view": {:hex, :phoenix_live_view, "0.16.4", "5692edd0bac247a9a816eee7394e32e7a764959c7d0cf9190662fc8b0cd24c97", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "754ba49aa2e8601afd4f151492c93eb72df69b0b9856bab17711b8397e43bba0"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"}, "phoenix_view": {:hex, :phoenix_view, "1.0.0", "fea71ecaaed71178b26dd65c401607de5ec22e2e9ef141389c721b3f3d4d8011", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "82be3e2516f5633220246e2e58181282c71640dab7afc04f70ad94253025db0c"}, + "pigeon": {:hex, :pigeon, "2.0.0-rc.0", "143a56262abe2eb79febedeea65ccae607abec5c59008af48796105098b5b89f", [:mix], [{:goth, "~> 1.3.0-rc.2", [hex: :goth, repo: "hexpm", optional: false]}, {:httpoison, "~> 0.7 or ~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:joken, "~> 2.1", [hex: :joken, repo: "hexpm", optional: false]}, {:kadabra, "~> 0.6.0", [hex: :kadabra, repo: "hexpm", optional: false]}], "hexpm", "b28da517e6a27bd1804fcbbe748e770cf43383a79b488fa33df62da3d3e078a8"}, "plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"}, "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},