react native Android Cannot access realm that has been closed - react-native

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.

Related

Env Variables not working for 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.

Using react native module (with native code) in expo project

I am working in an existing expo project (expo version 42.0.1 ) and I am unable to get this package working. It says in the package readme that it doesn't work with Expo, because it uses native code. But the readme is from a year ago and I thought Expo sdk42 allows you to use native modules now when you build your own custom client?
Does anyone know what I need to do to get this package working?
https://github.com/KjellConnelly/react-native-shared-group-preferences
Here's what i tried so far...
I added to my project with yarn add react-native-shared-group-preferences
And in App.js :
import 'expo-dev-client';
import React from 'react';
import { styles } from './src/components/CommonStyles';
import { useState } from 'react';
import { View, TextInput, Text } from 'react-native';
import SharedGroupPreferences from 'react-native-shared-group-preferences';
export default function App() {
const [inputText, setInputText] = useState('');
const widgetData = {
displayText: inputText,
};
const appGroupIdentifier = 'group.com.myproject.newwidget';
const handleSubmit = async () => {
try {
console.log('handleSubmit' + widgetData + appGroupIdentifier);
await SharedGroupPreferences.setItem(
'savedData', // this is a key to pull from later in Swift
widgetData,
appGroupIdentifier
);
} catch (error) {
console.log({ error });
}
};
return (
...
)
when I run the project with expo start and i to open iphone simulator,
I get this error: null is not an object (evaluating 'RNReactNativeSharedGroupPreferences.setItem')"
What am I doing wrong? Any help very much appreciated. Thanks

Firestore (9.1.3): Connection WebChannel transport erroned / Work on web browser but not on device mobiles (IOS/Android)

After upgrading from firebase v8 to v9 I have this problem, writing to firestore works fine in web browser but not on IOS / Android (no writing is done), after few minutes I have this warning:
#firebase/firestore:, Firestore (9.1.3): Connection, WebChannel transport errored:, me ...
summary of the code
import { initializeApp } from 'firebase/app'
import { getFirestore } from "firebase/firestore"
import { doc, setDoc } from "firebase/firestore"
const app = initializeApp(config)
const db = getFirestore(app);
const MyComponent = () => {
...
useEffect(() => {
(async function zda() {
await setDoc(doc(db, "users", "mario"), {
employment: "plumber",
outfitColor: "red",
specialAttack: "fireball"
})
})()
}, [])
By the way, I solved my problem with this line
const db = initializeFirestore(app, {useFetchStreams: false})

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.

Unhandled Network Error 401 When using Apollo in react native & empty graphql response

I am building a react-native app using create-react-native-app cli
Here are the packages I am using. All of the latest stable except fiber
"dependencies": {
"apollo-cache-inmemory": "^1.0.0",
"apollo-client": "^2.0.1",
"apollo-link": "^1.0.0",
"apollo-link-error": "^1.0.0",
"apollo-link-http": "^1.0.0",
"expo": "^21.0.0",
"graphql": "^0.11.7",
"graphql-tag": "^2.5.0",
"react": "16.0.0-alpha.12",
"react-apollo": "^2.0.0",
"react-native": "^0.48.4",
"react-navigation": "^1.0.0-beta.15"
}
The app runs and routing navigation works fine. I have two routes, App and FeedList.
the app talks to github graph api( I dont know if github access token is required, if so, i haved added it but I don't know if that's the correct way)
Feedlist is wrapped in a graphql HoC component and its props has a data which is already populated with results of the graphql request(even if the request fails)
You can refer to The structure of the data prop
App Component
import React, { Component } from 'react'
import ApolloClient from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo';
import { onError } from 'apollo-link-error';
import Router from './router'
class App extends Component {
createClient() {
const httpLink = createHttpLink({ uri: 'https://api.github.com/graphql'})
// handle network error
const errorLink = onError(({ networkError }) => {
if (networkError.statusCode === 401) {
console.log(networkError)
}
// let errorMessage = networkError.statusCode === 401 ? 'Network error 104, handled' : 'link sucess'
// console.log(errorMessage, networkError)
})
// apply widdleware to add access token to request
let middlewareLink = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
authorization: 'GITHUB_ACCESS_TOKEN'
}
})
return forward(operation)
})
const link = middlewareLink.concat(httpLink)
// Initialize Apollo Client with URL to our server
return new ApolloClient({
link: link,
cache: new InMemoryCache(),
})
}
render () {
return (
<ApolloProvider client={this.createClient()}>
<Router />
</ApolloProvider>
)
}
}
export default App
FeedList Component
import React, { Component } from 'react';
import { Text } from 'react-native';
import { graphql } from 'react-apollo';
import gql from 'graphql-tag';
// The data prop, which is provided by the wrapper below contains,
// a `loading` key while the query is in flight and posts when ready
const FeedList = ({ data }) => {
console.log(data) // returns default from HoC injected props
console.log('FeedList Eroor!!',data.error) // returns undefined
return data.error ? <Text> Error Fetching posts</Text>:<Text>fetching posts... </Text>
}
// The `graphql` wrapper executes a GraphQL query and makes the results
// available on the `data` prop of the wrapped component (PostList here)
export default graphql(gql`{
search(type: REPOSITORY, query: "react", first: 20) {
edges {
node {
... on Repository {
nameWithOwner
owner {
login
}
}
}
}
}
}`, { options: { notifyOnNetworkStatusChange: true } })(FetchPost);
The important parts are the the Wrapped FeedList component which does log the data from props and the createClient() method inside App component.
I followed this to try and catch the error that may happen during the data request.
The HoC wrapper component does its job and FeedList's data prop has has everything but the response from the api.
Note that the error does not crash app
The above image shows also the same error message as on the expo simulator on android
So I guess the question i have is
How do I catch the error? Here is a similar issue
If its the way I structured my query thats the problem. How do I correctly get the github api to return data correctl?
Here is the repo you can run and reproduce the error
Note that Issue#1 in that repo is similar to this SO question and I have already fixed it by handling data.error as per the documentation
Also note that most of the documentation is for the older versions of apollo-client > v2.x.x
Issue #2 is exactly what I am asking here. Thank you for your help
A 401 status means invalid authentication. As you've guessed, you need a valid OAuth token to send with your request. For development purposes, you can just generate one. Make sure you include the scopes outlines as outlined here:
user
public_repo
repo
repo_deployment
repo:status
read:repo_hook
read:org
read:public_key
read:gpg_key
You don't want users accessing the API through your credentials, so eventually you'll need to implement an OAuth2 authentication flow in your app to generate a token for each end user.