Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues getting Horizon working with React Native #255

Closed
dferber90 opened this issue Apr 17, 2016 · 22 comments
Closed

Issues getting Horizon working with React Native #255

dferber90 opened this issue Apr 17, 2016 · 22 comments

Comments

@dferber90
Copy link

I took horizon for a spin with a react-native project.

I have set up an example project you can use to experiment with it yourselves at dferber90/horizon-react-native.

Current issues

Currently there is at least one issue in here, because window.location is undefined in React Native.
After npm installing, it's possible to manually fix this by editing horizon-react-native/HorizonExampleApp/node_modules/@horizon/client/lib/auth.js and changing line 98

- var parsed = queryParse(window.location.search);
+ var parsed = queryParse(window && window.location && window.location.search);

After doing this, press CMD+R in the simulator. Now an alert should appear saying the Horizon client is connected... which means it works :)

Authentication

I haven't fully understood how horizon does authentication yet, so I can describe the problems I discovered only vaguely.

Tokens

When using tokens, the token would have to be stored on the device using AsyncStorage instead of localStorage. Having low-level functions which allow developers to pass the current token to Horizon from any source and specify how to save any new tokens would be helpful here.

OAuth

The current flow of using OAuth is probably not possible with React Native since the OAuth token can't be read form the callback URL, but maybe from the URI Scheme. I've never created OAuth integration for a native device before, so I can't really tell.

@deontologician deontologician added this to the Release 1.0 polish milestone Apr 17, 2016
@dalanmiller dalanmiller changed the title react-native Issues getting Horizon working with React Native Apr 20, 2016
@dalanmiller
Copy link
Contributor

dalanmiller commented Apr 20, 2016

var parsed = queryParse(window && window.location && window.location.search);

This seems like a reasonable fix albeit confusing if you don't have some React Native context, but that's fine.

Authentications, Tokens, & OAuth

If the endpoint is available and accessible by react-native and we can properly shim localStorage to AsyncStorage as you pointed out. you should be good for the rest of these things.

@dferber90 is there a browser friendly check we can do to check if AsyncStorage is available and opt for that first if it is available? Maybe just:

From => https://github.com/rethinkdb/horizon/blob/next/client/src/auth.js#L35-L50:

function getStorage() {
  if (window.AsyncStorage){      // Line added
    return new AsyncStorage()    // Line added
  } else if (window.localStorage === undefined) { // Line modified
    return new FakeStorage()
  }
  try {
    window.localStorage.setItem('$$fake', 1)
    window.localStorage.removeItem('$$fake')
    return window.localStorage
  } catch (error) {
    if (window.sessionStorage === undefined) {
      return new FakeStorage()
    } else {
      return window.sessionStorage
    }
  }
}

As for the token put into the query string, what is the standard way of ready from query params in react-native?

@deontologician
Copy link
Contributor

Put up a branch to solve outstanding issues in #279

@dferber90
Copy link
Author

As for the token put into the query string, what is the standard way of ready from query params in react-native?

I'm really new to react-native (1 week usage in my spare time) and haven't built anything with OAuth yet, so unfortunately I don't know. Take anything I say with a grain of salt 😉

@ndarilek
Copy link

So are these resolved, and should Horizon be working with React Native? I went through the various Horizon issues to get a sense of where it was, and this led me to believe that it still wasn't working. Then I watched the video at https://www.youtube.com/watch?v=xRK0SYSgVF0&feature=youtu.be and it does seem that it works. Am I missing something?

Thanks.

@deontologician
Copy link
Contributor

From what I can tell, the only remaining issue with React Native is that we don't interact with AsyncStorage instead of LocalStorage. The big impediment being that the interface is different (AsyncStorage is async). In addition, we'd need to figure out how best to do OAuth redirects in React Native, since there's not actually a browser or a window.location

@dferber90
Copy link
Author

When the app is closed or moved to the background the Websocket connection should be terminated, and reopened when the app is activated again. On React Native's side AppState can be used for this.

When the phone loses internet connectivity you'd have to handle that as well. NetInfo can be used for this. Specifically, you'd want to handle the case when it gains connection again to reconnect Horizon.

Both of these are concerns of the React Native developer, not Horizon itself as long as API is there to support reconnecting - and it seems there is 👍

Since these steps are pretty much the same for every React Native app, maybe we could extract them into an npm package.

@deontologician
Copy link
Contributor

That seems reasonable. I think we should get good reconnection working pretty soon it seems like.
Also, see #429 for how we might get around needing to abstract away AsyncStorage (at least for horizon's purposes)

@deontologician deontologician modified the milestones: Next Major Release, Medium term plans May 19, 2016
@deontologician deontologician modified the milestones: Next Major Release, Medium term plans Jun 21, 2016
@lirbank
Copy link
Contributor

lirbank commented Aug 19, 2016

The horizon client seems to work with react-native 0.31.0 (android+ios) and the the latest next branch of horizon, as long as I remove the babel config (as pointed out here #750).

@deontologician
Copy link
Contributor

That's good, I can probably move the babel config back out to a separate file. I forget exactly why I moved it in

@lirbank
Copy link
Contributor

lirbank commented Aug 19, 2016

Ok, great!

Oh, there is one more things that needs to be tweaked for it to work. Working on a fix. BRB.

@lirbank
Copy link
Contributor

lirbank commented Aug 19, 2016

WRT the babel config, if you remove it then ./setupDev.sh will not work anymore (eg SyntaxError: Unexpected token import).

It is still possible to build the client without the babel conf, with npm install.

EDIT: Or, ./setupDev.sh actually works but the hz cli it produces will not.

@lirbank
Copy link
Contributor

lirbank commented Aug 20, 2016

Ok, got it working. Assuming you have one project for your horizon app (horizonApp) and one for you react native app (reactNativeApp), the steps as of horizon 2.0.0-beta-7 are as follows:

  1. For android to work, apply this patch https://github.com/rethinkdb/horizon/pull/770/files
  2. Clone horizon git clone https://github.com/rethinkdb/horizon.git
  3. Disable the babel preset in horizon/client/package.json, ex https://github.com/lirbank/horizon/commit/8b62b2d115efcfab185d69ef2fde5c8672537d76
  4. Install your local horizon client in your react native app:
$ cd reactNativeApp
$ npm install ../horizon/client/ --save
  1. When you install the client above, you also break the cli (it needs the babel preset), so fix let's fix that. First re-enable the babel preset in horizon/client/package.json (eg. reverse step 3 above), then rebuild the client:
$ cd ../horizon/client/
$ npm install
  1. Start the horizon server (must be the latest server too, or else RN won't connect to it):
$ cd ../horizonApp/
$ node ../horizon/cli/src/main.js serve --dev --debug

Seems like a lot of steps, but it all boils down to that the Horizon cli must be built with the babel preset enabled while the Horizon client must be built without the babel preset for it to work in React Native.

@smkhalsa
Copy link

Thanks @lirbank for the workaround. Unfortunately, I'm getting this error when I try npm install ../horizon/client/ --save.

@horizon/client@2.0.0 prepublish /Users/smkhalsa/code/horizon/client
npm run compile && npm run build

@horizon/client@2.0.0 compile /Users/smkhalsa/code/horizon/client
node ./scripts/compile.js

module.js:457
throw err;
^

Error: Cannot find module 'shelljs/global'
at Function.Module._resolveFilename (module.js:455:15)
at Function.Module._load (module.js:403:25)
at Module.require (module.js:483:17)
at require (internal/module.js:20:19)
at Object. (/Users/smkhalsa/code/horizon/client/scripts/compile.js:1:63)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)

@smkhalsa
Copy link

I just tried it again, and it looks like it worked. I believe the only thing that changed was I reinstalled horizon globally.

@smkhalsa
Copy link

@deontologician can we implement this change so react-native can work out of the box?

@deontologician
Copy link
Contributor

Yes, we are going to, and I want to get a proper test setup for react
native so we dont accidentally break it again

On Thu, Aug 25, 2016, 23:04 Sat Mandir S. Khalsa notifications@github.com
wrote:

@deontologician https://github.com/deontologician can we implement this
change so react-native can work out of the box?


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
#255 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAAFVnNNd2oTgwczN09swAjjl53IwRmCks5qjoH7gaJpZM4IJH6s
.

@deontologician
Copy link
Contributor

deontologician commented Sep 13, 2016

Just an update, this isn't dead. I'm trying very hard to get react native up and running (endless configuration troubles). I now understand why you react native people are so persistent, it's a gauntlet getting the default app to work.

Update: It works!
selection_093

@deontologician
Copy link
Contributor

Ok, a fix is up in #823 if anyone wants to try it out. Be aware that if you do, you need to build the package and install it, you can't just npm link it since it will still pick up the babelrc file

@lirbank
Copy link
Contributor

lirbank commented Sep 15, 2016

Yes, #823 seems to solve the babel-loose problem!

@anhtuank7c
Copy link

@smkhalsa How do you pass these error?
I repeat npm install ../horizon/client/ --save again and again, still stuck.
I have horizon install global already.
:(
screen shot 2017-05-04 at 10 19 47 am

@kourindouhime
Copy link

@anhtuank7c
cd ../horizon/client
npm install
cd yourapp
npm install path-to-horizon/client --save

@davidroman0O
Copy link

Hope one day it i'll be fixed and we won't have to make all of this tricky hack! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants