Search code examples
elixirphoenix-frameworkphoenix-channels

phoenix presence fetch/2 override


I want to be able to pass user meta data through the :meta map in phoenix presence to access it from the JavaScript side. More specifically, I want to be able to push image file paths (strings) and have them associated with each user in my presence list. The documentation gives this example for overriding the fetch/2 function to add User model data into the :meta map:

def fetch(_topic, entries) do
  query =
    from u in User,
      where: u.id in ^Map.keys(entries),
      select: {u.id, u}

  users = query |> Repo.all |> Enum.into(%{})

  for {key, %{metas: metas}} <- entries, into: %{} do
    {key, %{metas: metas, user: users[key]}}
  end
end

However, when I make the appropriate changes for my User Model, I get errors regarding the variable u and the from/2 function as well as cannot use ^Map.keys(entries) outside of match clauses.

I went looking for examples of people trying to do similar things and was unable to find anything on github that is similar to what I am attempting here.

Anyone have any idea how I can go about restructuring the fetch/2 function so that it will work properly? I have a basic user model with 3 fields, email, password, and icon/avatar image.


Solution

  • You need to import Ecto.Query to use the from macro. This is done in your web.ex file so when you use MyApp.Web, :controller, you have it imported through the quote block in web.ex. However, you need to do this manually in other modules.

    Add the following to the top of your presence module like this

    defmodule MyApp.Presence do
      use Phoenix.Presence, otp_app: :my_app,
                            pubsub_server: MyApp.PubSub
      import Ecto.Query
      # ...
    end