Env Variables not working for React Native - react-native

I'm working on a React Native Web project with NextJS, so I have the React Native app and NextJS running those componentes with React Native web. I have a single .env file since it's all in a monorepo.
The env variables for NextJS are working, but they're not working for React Native, I have an app.config.js that consumes the .env and then I import with with expo-constants, for NextJS I did the same thing with next.config.js.
Before you ask, yes my .env is in the root folder.
This is the file where I'm using the variables:
import { FirebaseApp, FirebaseOptions, initializeApp } from "firebase/app";
import { Auth, getAuth } from "firebase/auth";
import { Platform } from "react-native";
import Constants from "expo-constants";
const isWeb = Platform.OS === "web";
const { FIREBASE_PUBLIC_API } =
Constants.manifest?.extra?.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY;
console.log(FIREBASE_PUBLIC_API);
const firebaseCredentials: FirebaseOptions = {
appId: isWeb ? process.env.NEXT_PUBLIC_FIREBASE_APP_ID : FIREBASE_PUBLIC_API,
apiKey: isWeb
? process.env.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY
: Constants.manifest?.extra?.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY,
authDomain: isWeb
? process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
: Constants.manifest?.extra?.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: isWeb
? process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID
: Constants.manifest?.extra?.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
};
let app: FirebaseApp | null = null;
let auth: Auth | null = null;
const initFirebase = () => {
if (!app) {
app = initializeApp(firebaseCredentials);
auth = getAuth();
}
return app;
};
This is the app.config.js:
export default {
name: "CoolApp",
version: "1.0.0",
extra: {
HASURA_GRAPHQL_ADMIN_SECRET: process.env.HASURA_GRAPHQL_ADMIN_SECRET,
HASURA_GRAPHQL_API_URL: process.env.HASURA_GRAPHQL_API_URL,
HASURA_GRAPHQL_CORS_DOMAIN: process.env.HASURA_GRAPHQL_CORS_DOMAIN,
NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY:
process.env.NEXT_PUBLIC_FIREBASE_PUBLIC_API_KEY,
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN:
process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
NEXT_PUBLIC_FIREBASE_PROJECT_ID:
process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET:
process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
FIREBASE_MESSAGING_SENDER_ID: process.env.FIREBASE_MESSAGING_SENDER_ID,
NEXT_PUBLIC_FIREBASE_APP_ID: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
FIREBASE_MEASUREMENT_ID: process.env.FIREBASE_MEASUREMENT_ID,
NEXT_PUBLIC_LOGROCKET_ID: process.env.NEXT_PUBLIC_LOGROCKET_ID,
NEXT_PUBLIC_MAPBOX_TOKEN: process.env.NEXT_PUBLIC_MAPBOX_TOKEN,
NEXT_PUBLIC_MAPBOX_STYLE: process.env.NEXT_PUBLIC_MAPBOX_STYLE,
},
};

React Native or Expo does not load .env for you. You have to use some library like dotenv and then use it in expo like this -
import 'dotenv/config';
export default {
name: 'CoolApp',
version: '1.0.0',
extra: {
HASURA_GRAPHQL_API_URL: process.env.HASURA_GRAPHQL_API_URL,
},
};
import Constants from 'expo-constants';
const { HASURA_GRAPHQL_API_URL } = Constants.manifest.extra;
You can read more about it in Expo documentation.

Related

react native Android Cannot access realm that has been closed

im using Realm inside my React native app, in IOS everything work fine, but with Android I always got this error: Cannot access realm that has been closed
here is my Realm:
RealmContext.js
import { ContactInfo, Room, RoomBackground, RoomDetail, RoomMessage, Summary } from "../database/RealmSchemas"
import { Realm, createRealmContext } from '#realm/react'
const config = {
schema: [Room.schema,
ContactInfo.schema,
RoomDetail.schema,
RoomBackground.schema,
Summary.schema,
RoomMessage.schema],
}
export default createRealmContext(config)
Other class
import RealmContext from '../../context/RealmContext'
const { useRealm, useQuery } = RealmContext
export class....{
const realm = useRealm()
const getRoomDetailFromDb = () => {
try {
const roomDetailDb = realm.objectForPrimaryKey('RoomDetail', room.RoomId)
if (roomDetailDb != null) {
roomDetail = JSON.parse(roomDetailDb.value)
}
} catch (error) {
console.log(error)
}
}
here is my version of realm:
"realm": "^10.18.0",
"#realm/react": "^0.3.0",
i did following the site: https://www.mongodb.com/docs/realm/sdk/react-native/use-realm-react/
Seems like react-native-reanimated lib is not compatible with Realm v10 on Android.
In case you use that please try realm#11.0.0-rc.0. It works fine after I upgrade realm version to v11. Even though it's not a stable version.

nuxt builder in nuxt3

Nuxt 2 was having builder which we used to build nuxt app.
But nuxt 3 is not having builder. Is that not part of nuxt 3? Following is what we were using in nuxt 2.
import { Builder } from '#nuxt/builder';
I am serving nuxt app from nestjs like following example of next.js.
https://github.com/hnviradiya/contact-list/blob/main/src/server/client-app/client-app.service.ts
Following is equivalent to Nuxt 2 code.
import { NestFactory } from '#nestjs/core';
import { AppModule } from './app.module.js';
import { loadNuxt } from 'nuxt3';
import { buildNuxt, Resolver } from '#nuxt/kit';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Check if we need to run Nuxt in development mode
const isDev = process.env.NODE_ENV !== 'production'
// Get a ready to use Nuxt instance
const nuxt = await loadNuxt({ rootDir: 'src/client-app/' })
// Enable live build & reloading on dev
if (isDev) {
buildNuxt(nuxt)
}
await app.listen(3001);
}
bootstrap();

Making global plugin that I can use anywhere in app

I have this class for sockets. Is there any way that I could make this globally accessible? I'd like to access the functions anywhere in my app for example like $socket.methodName()
What I've tried
class InitSocket {
constructor(options) {
this.options = options;
}
connect() {
console.log(this.options);
}
}
export default {
install: (Vue, options) => {
Vue.prototype.$socket = new InitSocket(options);
},
};
in main.js
const { createApp } = require('vue');
import App from "./App.vue";
import Sockets from './plugins/Socket'
const app = createApp(App);
app.use(Sockets , "test");
app.mount("#app");
But I am getting this message
Cannot set properties of undefined (setting '$socket') - What am I doing wrong?
In Vue 3 you can have multiple apps and you can no longer add to Vue prototype.
In order to write and use a plugin, follow the steps:
Step 1: Create the plugin
export default {
install: (app, options) => {
class InitSocket {
constructor(options) {
this.options = options;
}
connect() {
console.log(this.options);
}
}
// inject a globally available $socket() method
app.config.globalProperties.$socket = new InitSocket(options)
}
}
Step 2: Import and install it in main.js
import { createApp } from 'vue'
import App from "./App.vue";
import Sockets from './plugins/Socket'
const app = createApp(App);
app.use(Sockets , "test");
app.mount("#app");
Read more on the Vue docs: Plugins

Incorrect redirect link (spotify auth in expo app)

The problem is that the built app doesn't connect to spotify. But it works in dev mode.
Here is the context:
we have react native expo app
trying to connect to spotify via useAuthRequest from expo-auth-session (uses Linking under the hood).
sign-in-container.js:
import SignIn from './sign-in-component.js';
import { connect } from 'react-redux';
import {compose} from "ramda";
import React, {useEffect} from 'react';
import {isLogged} from "../../features/user-authentication/user-authentication-reducer";
import {signIn} from "../../features/user-authentication/user-authentication-saga";
import withGradient from "../../HOCs/with-gradient/with-gradient";
import {makeRedirectUri, useAuthRequest} from "expo-auth-session";
const mapStateToProps = state => ({
isLogged: isLogged(state),
});
const redirectUrl = makeRedirectUri();
const clientId = '***';
const discovery = {
authorizationEndpoint: 'https://accounts.spotify.com/authorize',
tokenEndpoint: 'https://accounts.spotify.com/api/token',
};
export default compose(
connect(mapStateToProps, {signIn}),
withGradient,
)(({ isLogged, signIn, navigation }) => {
const [request, response, promptAsync] = useAuthRequest(
{
clientId: clientId,
scopes: ['user-read-email', 'playlist-modify-public'],
usePKCE: false,
redirectUri: redirectUrl,
},
discovery
);
useEffect(() => {
if (response?.type === 'success') {
const { code } = response.params;
signIn(code);
}
}, [response]);
const handlePressSpotifyButton = () => {
promptAsync().then(() => {
navigation.navigate('Onboarding')
});
};
return <SignIn isLogged={isLogged} onPressSpotifyButton={handlePressSpotifyButton}/>;
});
And getting warning when start the project in dev mode (yarn start):
Linking requires a build-time setting scheme in the project's Expo
config (app.config.js or app.json) for production apps, if it's left
blank, your app may crash. The scheme does not apply to development in
the Expo client but you should add it as soon as you start working
with Linking to avoid creating a broken build. Learn more:
https://docs.expo.io/versions/latest/workflow/linking/
Without scheme it doesn't start via expo publish/expo build
Adding 'exp' as scheme for app.json config
"scheme": "exp"
After publishing get an error incorrect redirect link
redirection link in app:
started locally: exp://192.168.0.159:19000 (works)
published: exp://exp.host/#expo-user-name/my-app (incorrect)
How does the redirection link should look like to work not only in dev mode? Is adding 'exp' as scheme is correct?

How to get the device token in react native

I am using react-native 0.49.3 version, My Question is how to get the device token in react native for both IOS and Android I tried with this link but it not working for me, right now I tried in IOS. how to resolve it can one tell me how to configure?
I tried different solutions and I've decided to use React Native Firebase.
Here you will find everything about Notifications.
Also, you can use the others libraries that come with Firebase, like Analytics and Crash Reporting
After set up the library you can do something like:
// utils/firebase.js
import RNFirebase from 'react-native-firebase';
const configurationOptions = {
debug: true,
promptOnMissingPlayServices: true
}
const firebase = RNFirebase.initializeApp(configurationOptions)
export default firebase
// App.js
import React, { Component } from 'react';
import { Platform, View, AsyncStorage } from 'react-native';
// I am using Device info
import DeviceInfo from 'react-native-device-info';
import firebase from './utils/firebase';
class App extends Component {
componentDidMount = () => {
var language = DeviceInfo.getDeviceLocale();
firebase.messaging().getToken().then((token) => {
this._onChangeToken(token, language)
});
firebase.messaging().onTokenRefresh((token) => {
this._onChangeToken(token, language)
});
}
_onChangeToken = (token, language) => {
var data = {
'device_token': token,
'device_type': Platform.OS,
'device_language': language
};
this._loadDeviceInfo(data).done();
}
_loadDeviceInfo = async (deviceData) => {
// load the data in 'local storage'.
// this value will be used by login and register components.
var value = JSON.stringify(deviceData);
try {
await AsyncStorage.setItem(config.DEVICE_STORAGE_KEY, value);
} catch (error) {
console.log(error);
}
};
render() {
...
}
}
Then you can call the server with the token and all the info that you need.