feathersjs-ecosystem / client

[MOVED] Client side Feathers build
https://github.com/feathersjs/feathers
MIT License
111 stars 27 forks source link

Add documentation for using in React Native #10

Closed ekryski closed 8 years ago

ekryski commented 8 years ago

It's actually really simple. We just need to require the client but also load the socket library as described in this article. Easy peasy.

This is related to the main feathers issue #174.

ekryski commented 8 years ago

I'm going to start documenting stuff on here as we are still having some issues.

Socket.io works on react native. Therefore, feathers-client should work in react native. However, when doing things like in the linked article:

var React = require('react-native');
window.navigator.userAgent = "react-native";
var io = require('socket.io-client/socket.io');

There are a couple problems. Mainly, you are not able to use the chrome inspector to debug for a few reasons:

  1. Because the chrome debugger is running as a web worker it's idea of window.navigator is different than in your app (ie. you can't set the user agent).
  2. The Socket.io client by default supports JSON polling as a fallback mechanism. This in turn tries to access the document object. Because we are using react native and we are not in a browser we don't have a document object so it bombs.
ekryski commented 8 years ago

We also ran into an issue where the .babelrc file and babel definitions inside package.json for feathers-client are causes problems in react native. See #15.

ekryski commented 8 years ago

You can get around the window.navigator problem by first checking to see if it exists and is an object, like so:

if (window.navigator && Object.keys(window.navigator).length === 0) {
  window.navigator.userAgent = 'ReactNative';
}
ekryski commented 8 years ago

@corymsmith and I tried to get socket.io to not use JSON polling to see if that would work. It turns out that you can tell socket.io which transports to use in the client:

var io = require('socket.io-client/socket.io');

io('http://127.0.0.1:3000', { transports: ['websocket'] });

This seemed to allow it to work.

ekryski commented 8 years ago

One other issue we ran into was that feathers-client assumes a nodejs runtime. Therefore, the querystring and events modules need to be shimmed. The first thought was to just use the browserifed build (require('feathers-client/dist/feathers');) but that doesn't work because, again we are not in a browser.

Fortunately the solution is pretty simple. Just install those modules polyfills via npm and you are golden.

npm install --save events querystring
ekryski commented 8 years ago

In order to make this more plug and play with react native we're going to create another repo, specifically for a react native client that does all of these things for the user and just requires feathers-client as a dependency.

daffl commented 8 years ago

Thanks for writing that up. Hopefully we can make it work. Looking at the research it took it'll be really nice to have this working and documented. We should add events and querystring back in (@marshallswain I think then it'll also work directly with Steal again).

marshallswain commented 8 years ago

Sure thing.

ekryski commented 8 years ago

I'll put together a more comprehensive guide/walkthrough in the next couple days. Working on getting the waterline adapter and feathers errors up to date.

@daffl @marshallswain I'm ok with adding those deps to this repo but @corymsmith and I were also thinking that it would be better to wrap the react native client up in it's own repo, which uses this one as a dependency. So don't feel like we need to add querystring and events to this repo on the react native account. The added benefit of having it's own repo is that we can abstract away some of the BS for getting set up and make it so that in react native it is literally:

var feathers = require('feathers-react-native')();

var todoService = feathers.service('todos');
todoService.on('created', function (todo) {
  console.log('Todo created', todo);
});

You would also be able to do .configure and pass in your own socket or REST client but we would assume socket.io, superagent and disabling JSON polling by default so that you can get up and running quickly.

Facebook has their own Ajax, Websocket, and XMLHttpRequest implementation but because none of those are explored or would be way more work to implement, that's what I propose for a first cut. As far as I know we are the first people to get real websockets working in react native. All the other socket.io implementations have been using JSON polling. Websockets just landed in React Native Core in October.

If we find a way to merge the clients back really cleanly then we could always do that in the future. Thoughts?

marshallswain commented 8 years ago

The whole plan sounds good to me. If we keep those dependencies here, then they're useful for your react-native stuff and for Steal, but it looks like we really don't have to. @daffl the fate of the above PR is in your hands. :)

As far as I know we are the first people to get real websockets working in react native.

just awesome.

daffl commented 8 years ago

Could we do

var feathers = require('feathers-client');
var reactNative = require('feathers-react-native');
var app = feathers().configure(reactNative('http://path/to/websocket'));
var todoService = feathers.service('todos');

todoService.on('created', function (todo) {
  console.log('Todo created', todo);
});

I think we should try and make the feathers-client repo compatible to work with react-native if fixing Babel and adding querystring and events is everything that's needed. Otherwise you may end up duplicating potential future functionality (like batching).

ekryski commented 8 years ago

I added documentation for using each transport in React Native http://docs.feathersjs.com/clients/feathers.html and provider specific sub chapters.