Struggling to connect a working Phoenix soocket to a react native android front end

My Phoenix socket is working as expected (I tested using wscat)

defmodule ApifyWeb.PomodoroChannel do
  use ApifyWeb, :channel

  def join(_topic, _payload, socket) do
    {:ok, socket}
  end
end

Now to connect to my react native android front end, I installed Phoenix npm package (https://www.npmjs.com/package/phoenix) and added the following code to connect.

import React, { Component } from 'react';
import { Text, View, Button, StyleSheet } from 'react-native';
import { Socket } from 'phoenix';

const joinChannel = () => {
  const socket = new Socket("ws://localhost:4000/socket/websocket", {})
  
  socket.onOpen(event => console.log('Connected.'))
  socket.onError(event => console.log('Cannot connect.'))
  socket.onClose(event => console.log('Goodbye.'))
  
  socket.connect()
  
  const channel = socket.channel('pomodoro')
  channel.join()
    .receive('ok', resp => {console.log("Joined pomodoro channel", resp)})
    .receive('error', resp => {console.log("Error in joining", resp)})
}

const App = () => {
  return (
    <View>
      <View>
        <Button title={'Join Channel'} onPress={joinChannel} />
      </View>
    </View>
  );
};

export default App;

But I cannot seem to connect to the socket, as per mix phx.server logs that I have running. I just get Cannot connect. and Goodbye. on loop

Sun Nov 01 2020 16:58:05.281]  LOG      Cannot connect.
[Sun Nov 01 2020 16:58:05.283]  LOG      Goodbye.
[Sun Nov 01 2020 16:58:05.315]  LOG      Cannot connect.
[Sun Nov 01 2020 16:58:05.316]  LOG      Goodbye.
[Sun Nov 01 2020 16:58:05.382]  LOG      Cannot connect.
[Sun Nov 01 2020 16:58:05.383]  LOG      Goodbye.
[Sun Nov 01 2020 16:58:05.502]  LOG      Cannot connect.
[Sun Nov 01 2020 16:58:05.503]  LOG      Goodbye.
[Sun Nov 01 2020 16:58:05.670]  LOG      Cannot connect.
[Sun Nov 01 2020 16:58:05.671]  LOG      Goodbye.

I am sorry to have asked this Q involving react native but didn’t have any other forum that felt more appropriate.

1 Like

It looks good, and I have done it before with success with very similar configuration…

It’s not related to react native, because react use the same phoenix js.

But I suspect it might be incompatible version between server and client.

Which version of Phoenix?

Are You sure You use a compatible version of phoenix js?

What happens if You tyle npm i --prefix assets/ ?

I got it working by replacing localhost by hardcoded IP addres of my laptop. Also, I saw your 2017 post because of which I used the Phoenix js npm package so thanks for that. Since you have done it before, can I ask a Q. I will be further building the app, what I am wondering is how long will be the front end stay connected? Right now I can see while the app is in the foreground in my simulator, the channel is connected; so thats good. But were you able to stay connected to the socket while the app is minimized or worse killed? I think this Q might be more around react native and android battery optimizations rather than Phoenix Channels. If that is the case I apologize.

Also, will it be possible for you to share the code of your RN app using Phoenix sockets? It will be interesting for me to see.

Update - As expected, the app does not stay connected to channel when it is minimized, just tested it. Even after dropping the battery optimization of the app in emulator settings. I wonder if you have any pointers around it.

To access the local host of the machine that runs the android emulator you have to use 10.0.2.2.

Using localhost or 127.0.0.1 will point to the local host of the emulated device itself. On emulated iOS-devices with XCode, though, these point to the machine.

Regarding the second part of your question, I think you will get better anwers on an android forum. But I think this topic is also highly relevant to anyone that wants to use phoenix as backend for a native mobile app.

As far as I know, your app will get killed sooner or later by the android OS once in the background. There is no way to prevent this and keep a socket open. According to my experience, it happens very quickly on Samsung devices that run newer versions of android. The only way to reliably push to mobile clients is to go through Google’s Firebase service.

The backend implementation will have to keep track of user connections and
a) push incoming messages to offline clients
b) push undelivered messages to clients when their connection is removed.

Thanks. Yes it looks like I can use phoenix backend alongwith firebase notification service to push remote notifications to the android app. If I can do that, I think it will solve my problems.