Connecting React Native and Meteor backend w/o any 3rd party library in 2018

Arda Tanrikulu
Connecting React Native and Meteor backend w/o any 3rd party library in 2018 - The Guild Blog
Looking for experts? We offer consulting and trainings.
Explore our services and get in touch.

What was the problem and the existing solutions?

I was working on a project that has RN frontend and Meteor backend, but uses react-native-meteor npm package in RN project. I couldn’t share any code between them without struggling aliasing module import names and the other stuff.

I wanted to share the code between client and server like many Meteor projects do, because I was working on backend with a React Native developer who hadn’t know Meteor a lot. And, my TypeScript code will help him to write less error-prone code with type-checking feature of VSCode.

Then, I searched on Google for any alternative that makes the code sharing available.react-native-meteor package is quite useful, but is not able to share the code between client and server which Meteor does for Web.

I found a pretty old alternative called meteor-native-packages . It is a set of modified core packages of Meteor that replaces Browser API codes with React Native and NodeJS compatible ones . This idea makes Meteor Client work when they are bundled via meteor-client-bundler. However, all these need to be synced with Meteor’s native API which is really hard to maintain.

Also we have another problem; older meteor-client-bundler versions haven’t supported use of external node modules in the client project’s node_modules .

To summarize, there were various libraries and 3rd party solutions to connect React Native to Meteor such as react-native-meteor and meteor-native-packages with the challenge in meteor-client-bundler .

Solution: Browser Polyfills for Official Meteor Client

I’ve published a different package react-native-browser-polyfills that shims necessary APIs of browser to make Meteor’s official client compatible with React Native that is bundled by meteor-client-bundler .

I also added some features such as generating stub modules in node_modules directory to make meteor/PACKAGE_NAME syntax available, and support the use of external npm dependencies in the client project’s node_modules directory for the official meteor/react-meteor-data package instead of using the replication version in npm which has the same name. You can see more on the related post about MCB;

/blog/whats-new-on-meteor-client-bundler

As you know, Meteor has SockJS built-in which is compatible with both browser and NodeJS. So, the only problem is the code that uses DOM API. Luckily, WebSocket has already been implented by React Native. There is another savior for the rest.

react-native-browser-polyfills has been just released for polyfilling DOM API including localStorage , navigator.connection , document.location and some other subsets that uses React Native API equivalent ones.

AsyncStorage is used for localStorage , NetInfo is used for navigator.connection and Linking is used for document.location . But, the problem is that these APIs from React Native are asynchronous while they are synchronous in browser. As a workaround, react-native-browser-polyfills waits for resolving their promises, then emits DOMContentsLoaded for document which Meteor Client would be waiting for in order to initiate the connection between RN and Meteor backend.

Also we have Facebook, Twitter and Google Login on React Native and Meteor stack

This was the most challenging one which is solved by another package react-native-meteor-polyfills that extends react-native-browser-polyfills .

I’ve released another package react-native-meteor-polyfills to polyfill window.open with Linking by extending react-native-browser-polyfills. However, this polyfill must be included to Meteor project as well to make it able to redirect to the RN app after a successful OAuth login.

Thanks to this polyfill, you can use accounts-{SERVICE_NAME} packages without any extra native libraries.

Easy Start with Boilerplate

Just check out this up-to-date boilerplate;

https://github.com/DAB0mB/ReactNativeMeteorBoilerplate

How To Add All These To Your Existing Project

If you want to learn more to integrate all these features to your existing RN and Meteor projects step-by-step;

  • First, install react-native-meteor-polyfillsin both Meteor and RN projects.
# For Meteor Project
meteor npm install react-native-meteor-polyfills--save
# For React Native Project
yarn add react-native-meteor-polyfills
# or
npm install react-native-meteor-polyfills--save
  • Install meteor-client-bundler in your RN project
//For React Native Project
yarn add meteor-client-bundler --dev
//or
npm install meteor-client-bundler --save-dev
  • Add meteor-client.config.json ;
{
  "runtime": {
    // These variables should be pointed to your Meteor server.
    "DDP_DEFAULT_CONNECTION_URL": "http://localhost:3000",
    "ROOT_URL": "http://localhost:3000"
  },
  "externalNpmPackages": [
    "react" // Use `react` from `node_modules`
  ],
  "generateNodeModules": true //Generate for `meteor/PACKAGE_NAME`
}
  • Add postinstall to your package.json of your RN project, because generated meteor-client.js and other stub modules might be deleted. This script will restore them after each node_modules install.
{
  /*...*/
  "scripts": {
    "postinstall": "meteor-client bundle -s {PATH_OF_METEOR_PROJECT}"
    /*...*/
  }
}
  • Finally, run this script to generate those modules.
  • After that do not forget to include react-native-meteor-polyfills/client and meteor-client in the top of React Native entry file App.jsx or index.*.js etc.
import 'meteor-client';
import 'react-native-meteor-polyfills';

If you never used Meteor with React before, check out Meteor’s official documentation for react-meteor-data package, and OAuth packages.

And, YOUR NEW STACK IS READY TO RUN!

Optional: Facebook, Twitter and Google Login Support

  • If you want to make Meteor.loginWith work with React Native, you have to add custom URI scheme to your React Native project.
  • Then, tell Meteor what your URI scheme is;
import { setApplicationPrefix } from 'react-native-meteor-polyfills/server';

setApplicationPrefix('myURIscheme');

Contribution

If you find any bugs, problems and issues, please open a new issue on GitHub. If you solve any of them, please feel free to push a pull request.

I’d appreciate your claps and comments for this post!

Credits

Special thanks to;

  • Eytan Manor
  • Uri Goldshtein