Facebook/Google Login: A Solution with React-Native-Meteor
Introduction
Disclaimer
This article is not a 100%-original walkthrough but a derivative design and implementation inspired by Spencer Carli and other open-source implementations.
All code snippets shown in this article are from public open-source projects. The proprietary part will not be provided here.
Tech Stack: Understanding Meteor.js
The Meteor web tech stack is a mature web full-stack solution. In the Meteor land, we’re used to luxuries like automatically synced data or being able to write database queries using the same syntax on the client and server. You may not have heard of Meteor before, but its successor, Apollo, is widely known for the popular GraphQL. It gives you more control but also requires writing more logic yourself.
When it comes to mobile, the maturity might become a problem. As the combo of React-Native-Meteor is quite rare, the 3rd party package React-Native-Meteor has not been updated for 2 years. On the other hand, it’s still the best solution so far if you don’t want to build your own wheel.
The target backend uses Meteor.Accounts for user login and authentication as part of the mature solution, including social login. However, Meteor.Accounts APIs are not available on mobile (React Native). So, developers need to find a third-party package or SDK to finish the FB login and Google login.
If developers are looking for a 3rd party package to solve this with yarn or npm install, they may want the desired package to be compatible with the frontend React-Native-Meteor and the backend Meteor.Accounts package at the same time.
Unfortunately, there was none like this.
Spencer Carli was able to implement the Facebook login by writing his own Facebook login handler. Then, for Google login, he basically followed his GitHub project.
Thus, based on Spencer’s great work, it’s time for developers to refactor their own wheels.
The Challenge: Meteor in Mobile Environment
The Problem:
- Meteor.Accounts social login APIs don’t work on React Native
- No existing npm package provides both React-Native-Meteor compatibility AND Meteor.Accounts backend integration
- The official React-Native-Meteor package hasn’t been updated in 2 years
- Developers must bridge the gap between native SDKs and Meteor’s authentication system
Why It Matters:
- Unified authentication across web and mobile is crucial for user experience
- Manual token management without proper integration leads to security issues
- Building custom solutions from scratch is time-consuming and error-prone
Workflow Overview
Here is the workflow, inspired by Spencer Carli.
Spencer didn’t provide the database CRUD details because the database and web social login solutions may vary. He used the default LoginButton component provided by the Facebook SDK, so we need to create our own custom social login components.
The Authentication Flow:
User Action (Mobile App)
↓
Native SDK Login (Facebook/Google)
↓
Token Retrieval from SDK
↓
Send Token to Meteor Server
↓
Meteor Login Handler Processes Token
↓
Generate Meteor-Stamped Token
↓
Store Token & User ID Locally
↓
User Authenticated
Legend:
- Red circled: Spencer Carli’s design
- Uncircled: Original implementation
Social Login Backend
Facebook Login Backend
Here, Spencer Carli elaborated his flow in these two articles. It’s not hard to follow and implement, so links are provided here for records.
Medium article: Spencer Carli’s Facebook Login Implementation
Github project: React Native Meteor Facebook Login
Google Login Backend
Github project: React Native Meteor Google Login
Using Accounts Methods to Stamp and Upsert Services
Here, Spencer didn’t provide the database CRUD details because the database and web social login solutions may vary. In general, Meteor.Accounts is one of the most widely used packages for social login with the Meteor web solution.
After dismantling the source code of Meteor.Accounts, here is the implementation of Meteor server token generation:
Accounts.registerLoginHandler('facebookMobile', ({ options }) => {
//*** Auth part
const stampedToken = Accounts._generateStampedLoginToken()
const hashStampedToken = Accounts._hashStampedToken(stampedToken)
Meteor.users.update(userId, {
$push: { 'services.resume.loginTokens': hashStampedToken }
})
return {
_id: userId,
userId: userId,
token: stampedToken.token
}
})
After Facebook/Google Auth succeeded, the Meteor.Accounts package’s source code came with two methods to upsert the services.resume.loginTokens, in order to make the mobile users get consistent login info as web users.
Social Login Frontend
Set Up
For the React Native part, it’s recommended to use these packages:
{
"react-native-google-signin": "^2.0.0", // for RN 0.60+, try @react-native-community/google-signin
"react-native-fbsdk": "^0.10.1" // or RN 0.60+, try react-native-fbsdk 1.0+
}
Google: react-native-google-signin
Facebook: react-native-fbsdk
Critical Implementation Steps
Here, Spencer created a MeteorGoogleLoginManager to handle everything with Google login on the Mobile (React Native) side, with the help of the MeteorCommunicationManager Class created previously for handling the communication with our Meteor Server.
Step 1: Configure the Service
Configure the service to get the token from Google/Facebook auth services via the mobile SDK.
import { YourMeteorCommunicationManager } from './'
export default class YourMeteorGoogleLoginManager {
static configureGoogleSignIn() {
GoogleSignin.configure({
webClientId: ENV_CONFIG.google.webClientId,
offlineAccess: false
})
}
// ... other methods
}
Step 2: Implement Native SDK Login
static async loginWithGoogle() {
try {
await GoogleSignin.hasPlayServices()
const userInfo = await GoogleSignin.signIn()
const { idToken, accessToken } = await GoogleSignin.getTokens()
// Send tokens to Meteor server
return await MeteorCommunicationManager.callMethod(
'loginWithGoogleMobile',
{ idToken, accessToken }
)
} catch (error) {
console.error('Google login error:', error)
throw error
}
}
Step 3: Handle Server Response
The last step: Store the ID and Meteor-generated token in AsyncStorage and the local Meteor object, respectively.
// Same for Google/Facebook login
static YourMeteorAuthCallback = (err, res, cbk, failCbk) => {
if (!err && !!res) {
// Save user ID and token
const Data = Meteor.getData()
AsyncStorage.setItem(ENV_CONFIG.USER_TOKEN_KEY, res.token)
Data._tokenIdSaved = res.token
Meteor._userIdSaved = res.id
cbk && cbk(res)
} else {
AsyncStorage.removeItem(ENV_CONFIG.USER_TOKEN_KEY)
failCbk && failCbk(err)
}
}
Implementation Considerations
Token Storage
- Store Meteor tokens securely using AsyncStorage
- Keep tokens synchronized with Meteor’s local collection
- Implement token refresh logic for long-lived sessions
Error Handling
- Handle network failures gracefully
- Implement retry logic for failed authentication attempts
- Provide clear error messages to users
Platform Differences
- iOS requires URL scheme configuration
- Android requires Google Services compatibility check
- Handle platform-specific OAuth flows
Security Best Practices
- Never commit credentials to version control
- Use environment variables for API keys and secrets
- Validate tokens on the server side
- Implement proper session management
- Use HTTPS for all OAuth communications
Testing Strategy
- Test login flows on both iOS and Android devices
- Verify token persistence across app restarts
- Test error scenarios (network failures, user cancellation)
- Validate token refresh mechanisms
- Ensure proper logout functionality
Conclusion
Implementing social authentication with React Native and Meteor requires bridging the gap between native SDKs and Meteor’s authentication system. While challenging, the approach pioneered by Spencer Carli provides a solid foundation for developers who need this functionality.
The key to success is understanding:
- How Meteor.Accounts works internally
- How to properly bridge native authentication with Meteor’s token system
- How to maintain security while providing a seamless user experience
By following this approach, developers can achieve unified authentication across web and mobile platforms while leveraging Meteor’s robust backend infrastructure.
References
- Spencer Carli’s solution (2016, Meteor 1.3): Article Link
- mgscreativa’s solution (2016, Meteor 1.5.1): Article Link
- Official module with the newest Meteor version: Meteor Accounts Package