I am facing an issue for the last 2 weeks. I was able to connect successfully my React Native app to Firebase and could see the details on the Firebase console. However, 2 weeks back the app suddenly stopped working. All I see now is a white screen. I am trying to capture Facebook Login through Firebase and tried removing firebase code and was successfully able to connect with the FB(So I guess the issue is with Firebase connection).
Any pointers will be highly appreciated.
Here is my code
App.js
import React from 'react';
import Login from './screens/Login';
import reducers from './redux/reducers';
import thunkMiddleware from 'redux-thunk';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
const middleware = applyMiddleware(thunkMiddleware)
const store = createStore(reducers, middleware);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<Login/>
</Provider>
);
}
}
Login Screen
import React from 'react';
import styles from '../styles'
import NavigationContainer from '../navigation/RootNavigator';
import { connect } from 'react-redux';
import { login } from '../redux/actions'
import * as firebase from 'firebase';
import firebaseConfig from '../config/firebase.js'
import * as Facebook from 'expo-facebook';
firebase.initializeApp(firebaseConfig);
import {
Text,
View,
Alert,
TouchableOpacity
} from 'react-native';
class Login extends React.Component {
state = {}
UNSAFE_componentWillMount() {
firebase.auth().onAuthStateChanged((user) => {
if (user != null) {
this.props.dispatch(login(true))
console.log("We are authenticated now!" + JSON.stringify(user));
}
});
}
login = async () => {
try {
await Facebook.initializeAsync({
appId: '1742056282625463',
});
const {
type,
token,
} = await Facebook.logInWithReadPermissionsAsync({
permissions: ['public_profile'],
});
if (type === 'success') {
// Get the user's name using Facebook's Graph API
const response = await fetch(`https://graph.facebook.com/me?access_token=${token}`);
Alert.alert('Logged in!', `Hi ${(await response.json()).name}!`);
// Build Firebase credential with the Facebook access token.
const credential = await firebase.auth.FacebookAuthProvider.credential(token);
// Sign in with credential from the Facebook user.
firebase.auth().signInWithCredential(credential).catch((error) => {
// Handle Errors here.
Alert.alert("Try Again")
});
} else {
// type === 'cancel'
Alert.alert("Cancel")
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
render() {
if(this.props.loggedIn){
return (
<NavigationContainer/>
)
} else {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.login.bind(this)}>
<Text>{this.props.loggedIn}</Text>
</TouchableOpacity>
</View>
)
}
}
}
function mapStateToProps(state) {
return {
loggedIn: state.loggedIn
};
}
export default connect(mapStateToProps)(Login);
Firebase
var firebaseConfig = {
apiKey: "AIzaSyCWjS5WxFgaBajsWKQPFLbC9QekmyxiO7I",
authDomain: "bookworm-d8e9f.firebaseapp.com",
databaseURL: "https://bookworm-d8e9f.firebaseio.com",
projectId: "bookworm-d8e9f",
storageBucket: "bookworm-d8e9f.appspot.com",
messagingSenderId: "1097080341399",
appId: "1:1097080341399:web:767ce9b106a13ae103bad2",
measurementId: "G-2JY9B79XCC"
};
// Initialize Firebase
//firebase.initializeApp(firebaseConfig);
//firebase.analytics();
module.exports = firebaseConfig
Redux - Action
export function login(input){
return function(dispatch){
dispatch({ type: 'LOGIN', payload: input });
}
}
Redux - Reducers
export default reducers = (state = {
loggedIn: false,
}, action) => {
switch (action.type) {
case 'LOGIN': {
return { ...state, loggedIn: action.payload }
}
}
return state;
}
Related
i'm trying to refencer a realtime database at my reactjs aplication but it's not working.I created a file for firebase config named firebase.js and i import that one in ./home/index.js
Visual Studio code does not report the error, but when i look the DevTool report 3 errors.
1.Uncaught TypeError: firebase__WEBPACK_IMPORTED_MODULE_1_.default.app.ref is not a function
2.The above error occurred in the component
3.Uncaught (in promise) TypeError: firebase__WEBPACK_IMPORTED_MODULE_1_.default.app.ref is not a function
1.firebase.js
import {initializeApp}from 'firebase/app';
import { getAuth} from 'firebase/auth';
import { getDatabase} from 'firebase/database';
const firebaseAPP =initializeApp( {
apiKey: "AIzaSyCtYdRuFmkC3Mx7dcRLBcY-HYPitRuMD2Y",
authDomain: "reactproject-2d567.firebaseapp.com",
databaseURL:"https://reactproject-2d567-default-rtdb.firebaseio.com/",
projectId: "reactproject-2d567",
storageBucket: "reactproject-2d567.appspot.com",
messagingSenderId: "199332161332",
appId: "1:199332161332:web:828be709a4d0109df62761",
measurementId: "G-F517JH6WEJ"
});
const auth = getAuth(firebaseAPP)
const db = getDatabase(firebaseAPP)
class Firebase{
constructor(){
this.app = getDatabase(firebaseAPP);
}
//metodo de login
login(email,password){
return auth.signInWithEmailAndPassword(email,password)
}
async register(nome,email,password){
await auth.createUserWithEmailAndPassword(email,password)
const uid= auth.currentUser.uid
return db.ref('usuario').child(uid).set({nome:nome})
}
isInitialized(){
return new Promise(resolve =>{
auth.onAuthStateChanged(resolve)
})
}
}
export default new Firebase();
2../home/index.js
import React, { Component } from 'react';
import firebase from '../../firebase';
import './home.css'
class Home extends Component {
state ={
posts:[]
}
componentDidMount(){
firebase.app.ref('posts').once('value', (snapshot)=>{
let state = this.state;
state.posts =[]
snapshot.forEach((childItem)=>{
state.posts.push({
key:childItem.key,
titulo:childItem.val().titulo,
image:childItem.val().image,
descricao:childItem.val().descricao,
autor:childItem.val().autor,
})
})
this.setState({state})
})
}
render(){
return(
<div> home</div>
)
}
}
export default Home
I was working on a react project in which I wanted to implement google sign in so I used firebase and wrote the following code:
import {initializeApp} from "firebase/app";
import "firebase/auth";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "****",
authDomain: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***"
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
export default app;
Creating Context to make the function accessible in the whole application:
import React from 'react';
import FirebaseContext from './FirebaseContext';
import { auth } from '../Firebase/firebase';
import { signInWithRedirect,GoogleAuthProvider,createUserWithEmailAndPassword } from "firebase/auth";
const FirebaseState = (props)=>{
const reactSignup = (email,password)=>{
return createUserWithEmailAndPassword(auth,email,password);
}
const googleSignin = ()=>{
const provider = new GoogleAuthProvider();
return signInWithRedirect(auth,provider);
}
return(
<FirebaseContext.Provider value={{reactSignup,googleSignin}}>{props.children}</FirebaseContext.Provider>
)
}
export default FirebaseState;
Calling the function on the desired button click
const {googleSignin} = useContext(FirebaseContext);
const handleGoogleSignin = async()=>{
try{
console.log("Sign in attempted");
await googleSignin();
history.push("/main");
}catch(err){
console.log(err);
}
}
Now the problem is that whenever I am running application using npm run start and the button is clicked it does not redirect for sign in but when the application is stopped then it is able to redirect but as my application is no more running that is of no use.
30 sec screen recording of the problem
Do you try to change signInWithRedirect to signInWithPopup ?
So
import React from 'react';
import FirebaseContext from './FirebaseContext';
import { auth } from '../Firebase/firebase';
import { signInWithPopup,GoogleAuthProvider,createUserWithEmailAndPassword } from "firebase/auth";
const FirebaseState = (props)=>{
const reactSignup = (email,password)=>{
return createUserWithEmailAndPassword(auth,email,password);
}
const googleSignin = ()=>{
const provider = new GoogleAuthProvider();
return signInWithPopup(auth,provider);
}
return(
<FirebaseContext.Provider value={{reactSignup,googleSignin}}>{props.children}</FirebaseContext.Provider>
)
}
export default FirebaseState;
Alternative Idea
Detact signInWithRedirect from Context and use the funct directly in your component function like this:
import { auth, provider } from '../../config';
import { signInWithPopup } from '#firebase/auth';
import { Button } from '#chakra-ui/button';
export default function Signup() {
const loginWithGoogle = () => {
signInWithPopup(auth, provider);
};
return (
<div>
<Button onClick={loginWithGoogle}>Signin With Google</Button>
</div>
);
}
Alternative Idea 2
Go to Firebase Panel > Authentication > Sign-in Method
Check your domain, if your domain is in the list delete and add again. Else add your domain.
I'm getting this weird error in my react-native app. Where I'm using redux to save the user when its is fetched from the firebase database.
Here is the error:
and here is my code in App.js:
import { StatusBar } from 'expo-status-bar';
import React, { useEffect } from 'react';
import { StyleSheet, Text, View, ToastAndroid } from 'react-native';
import firestore from '#react-native-firebase/firestore';
import RNBootSplash from "react-native-bootsplash";
import auth from '#react-native-firebase/auth';
// Navigation
import { NavigationContainer } from '#react-navigation/native';
import BottomTabNavigator from './src/navigation/BottomTabNavigation';
import AuthenticationStack from './src/navigation/AuthenticationStack';
// redux imports
import { Provider } from 'react-redux';
import { saveUserPrefs, saveUser } from './src/redux';
import {store} from './src/redux'
import { connect } from 'react-redux';
const App = (props) => {
const { saveUserPrefs, saveUser } = props;
let isLoggedIn = false;
useEffect(() => {
auth().onAuthStateChanged((user) => {
// if not already login go back to login screen
if(!user){
isLoggedIn = false;
} else {
isLoggedIn = true
RNBootSplash.hide({ fade: true }); // hide the splash screen
ToastAndroid.show("Logged In", ToastAndroid.SHORT);
// save the user & userPrefs in store (redux)
saveUser(user);
saveUserPrefs(user.uid);
}
});
}, [])
return (
<Provider store={store}>
<NavigationContainer>
{isLoggedIn ? <BottomTabNavigator /> : <AuthenticationStack />}
</NavigationContainer>
</Provider>
);
}
const mapStateToProps = (state) => ({
userReducer: state.userReducer
})
export default connect(mapStateToProps, { saveUserPrefs , saveUser})(App);
and here is my redux code:
import axios from 'axios';
import thunk from 'redux-thunk';
import { combineReducers, createStore, applyMiddleware } from 'redux'
import firestore from '#react-native-firebase/firestore';
// Actions
export const saveUserPrefs = (userId) => {
return async (dispatch) => {
try {
console.log('in userlogin function');
const data = await firestore().collection('Users').doc(userId).collection('userPrefs').get();
dispatch({ type: 'SAVE_USER_PREFS', payload: data.docs[0]._data });
} catch (err) {
dispatch({ type: 'ON_ERROR', payload: err });
}
}
}
export const saveUser = (user) => {
return async (dispatch) => {
try {
dispatch({ type: 'SAVE_USER', payload: user})
} catch (err) {
dispatch({ type: 'ON_ERROR', payload: err });
}
}
}
// reducers
const userReducer = (state = {}, action) => {
switch(action.type){
case 'SAVE_USER_PREFS':
return {
...state,
userPrefs: action.payload
}
case 'SAVE_USER':
return {
...state,
user: action.payload
}
case 'ON_ERROR':
return {
...state,
appError: action.payload
}
default:
return state;
}
}
// root reducer
export const rootReducer = combineReducers({
userReducer,
})
// store
export const store = createStore(rootReducer, applyMiddleware(thunk));
I'm new to redux but I read that I have to put the connect method in the component I'm using to get the actions in order to save in the store.
in the App component you cannot connect to the reduxjust wrap your App within another component, that have the Provider
Example code
const AppWrapper = () => {
return (
<Provider store={store}>
<App />
</Provider>
);
};
And remember to delete <Provider store={store}> in your App component
I am working on a simple React Native app to read and write data from a Firebase database. My read and write permissions in Firebase have been set to true:
{
"rules": {
".read": true,
".write": true,
}
}
Here are my relevant files:
App.js
import React from 'react'
import {View, StyleSheet, Button} from 'react-native'
import * as firebase from 'firebase'
import RootStackNavigator from './navigation/RootNavigation'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
isLoadingComplete: false
}
var firebaseConfig = {
apiKey: "xxxxxxx",
authDomain: "testproject-9d0bc.firebaseapp.com",
databaseURL: "https://testproject-9d0bc-default-rtdb.firebaseio.com",
projectId: "testproject-9d0bc",
storageBucket: "testproject-9d0bc.appspot.com",
messagingSenderId: "1003049293166",
appId: "1:1003049293166:web:1df37fd6d181cf895cdd7f"
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig)
} else {
firebase.app()
}
}
render() {
return (
<View style={styles.container}>
<RootStackNavigator/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
});
RootStackNavigation.js
import React from 'react';
import { createAppContainer, StackNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import HomeScreen from '../src/screens/HomeScreen';
const RootStackNavigator = createStackNavigator(
{
screen: HomeScreen
},
{
initialRouteName:"screen", // first component that should be displayed
defaultNavigationOptions: {
title: "App"
}
}
);
export default createAppContainer(RootStackNavigator)
HomeScreen.js
import React from "react";
import { Text, StyleSheet, View, Button, TouchableOpacity } from "react-native";
import * as firebase from "firebase";
const HomeScreen = (
props
) => {
function getData() {
firebase
.database()
.ref("people/")
.on("value", (snapshot) => {
const age = snapshot.val().age;
console.log("Age: " + age);
});
}
return (
<View>
<Text>Hello this is the home screen</Text>
<Button title="Get Data" onPress={getData} />
</View>
);
};
const styles = StyleSheet.create({
text: {
fontSize: 30,
},
});
export default HomeScreen;
My firebase database looks like this (all data was manually added through the firebase website)and I want to be able to print out these items after pressing the "Get Data" button to the console as shown in my getData function in HomeScreen.js
However, my code in getData does not work and nothing prints out to my console. What am I missing here?
Kindly modify this in your code
firebase.database.ref("people").on("value", snapshots => {
let peoples = [];
snapshots.forEach((snapshot) => {
peoples.push(snapshot.val().age);
console.log(snapshot.val().age);
});
// here you can set this Array
// setPeople(peoples)
Figured out my issue. As you can see in my firebase database, the way I was accessing my data was wrong. If I wanted to get the age of "dad", I should have called snapshot.val().dad.
I have made login and logout actions and userReducer. How can I integrate AsyncStorage with Redux? I am using Redux Thunk as a middleware.
I am able to implement login and logout using internal state variable but I am not able to understand how to break it down into action and reducer as well as make use of AsyncStorage for storing accessToken.
Original Code:
_onLogin = () => {
auth0.webAuth
.authorize({
scope: 'openid profile',
audience: 'https://' + credentials.domain + '/userinfo'
})
.then(credentials => {
this.setState({ accessToken: credentials.accessToken });
})
.catch(error => console.log(error));
};
_onLogout = () => {
if (Platform.OS === 'android') {
this.setState({ accessToken: null });
} else {
auth0.webAuth
.clearSession({})
.then(success => {
this.setState({ accessToken: null });
})
.catch(error => console.log(error));
}
};
loginAction.js:
import { LOGIN_USER } from './types';
import Auth0 from 'react-native-auth0';
var credentials = require('./auth0-credentials');
const auth0 = new Auth0(credentials);
export const loginUser = () => dispatch => {
auth0.webAuth
.authorize({
scope: 'openid profile',
audience: 'https://' + credentials.domain + '/userinfo'
})
.then(credentials =>
dispatch({
type: LOGIN_USER,
payload: credentials.accessToken
})
)
.catch(error => console.log(error));
}
logoutAction.js:
import { LOGOUT_USER } from './types';
import Auth0 from 'react-native-auth0';
var credentials = require('./auth0-credentials');
const auth0 = new Auth0(credentials);
export const logoutUser = () => dispatch => {
auth0.webAuth
.clearSession({})
.then(success =>
dispatch({
type: LOGOUT_USER,
payload: null
})
)
.catch(error => console.log(error));
}
userReducer.js:
import { LOGIN_USER, LOGOUT_USER } from '../actions/types';
const initialState = {
accessToken: null
}
export default function (state = initialState, action) {
switch (action.type) {
case LOGIN_USER:
_storeData = async () => {
try {
await AsyncStorage.setItem('accessToken', action.payload);
} catch (error) {
console.log(error)
}
}
return {
...state,
accessToken:action.payload
};
case LOGOUT_USER:
_removeData = async (accessToken) => {
try {
await AsyncStorage.removeItem(accessToken);
} catch (error) {
console.log(error)
}
}
return {
...state,
accessToken:action.payload
};
default:
return state;
}
}
I am new to Redux so I tried converting original code into actions and reducers but I am not sure whether I have implemented AsyncStorage in userReducer.js correctly?
To persist redux state I recommend you redux-persist.
Installation:
npm i -S redux-persist
Usage:
First, configure redux store
// configureStore.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
Then, wrap your root component with PersistGate
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
You can conveniently use AsyncStorage alone OR redux to manage authentication state. Depends on which you are comfortable with. I will give you an example of both.
For AsyncStorage:
Assuming you have authentication keys that is valid for 2 weeks only. You can take note when your user logs in and save the time. eg:
//LoginScreen
import { onSignIn } from '../actions/auth'; //I will describe the onSignInMethod below
import axios from 'axios'; //lets use axios. You may use fetch too.
export default class LoginScreen extends Component {
//your code: state, static etc
loginMethod = () => {
const url = yourauthUrl;
const payload = {
email: this.state.email,
password: this.state.password
};
axios.post(url, payload)
.then((response) => {
if (response.status == 200) {
const dateOfLastLogin = new Date().getTime().toString(); //take note of the time the user logs in.
AsyncStorage.setItem('dateOfLastLogin', dateOfLastLogin);
}
})
.then(() => {
onSignIn() //onSignIn handles your sign in. See below.
.then(() => this.props.navigation.navigate('AfterSignInPage'));
})
.catch(() => { // your callback if onSignIn Fails
});
})
.catch((error) => { //your callback if axios fails
});
}
}
In ../actions/auth.js
import { AsyncStorage } from 'react-native';
export const onSignIn = () => AsyncStorage.setItem('auth_key', 'true');
//in LoginScreen we called this to set that a user has successfully logged in
//why is true a string? -- Because Asyncstorage stores only strings
export const onSignOut = () => AsyncStorage.multiRemove(['auth_key', 'dateOfLastLogin']);
//now lets create a method that checks if the user is logged in anytime
export const isSignedIn = () => {
return new Promise((resolve, reject) => {
AsyncStorage.multiGet(['auth_key', 'dateOfLastLogin'])
.then((res) => {
const userKey = res[0][1];
const lastLoginDate = parseInt(res[1][1]);
const today = new Date().getTime();
const daysElapsed = Math.round(
(today - lastLoginDate) / 86400000
);
if (userKey !== null && (daysElapsed < 14)) {
resolve(true);
} else {
resolve(false);
}
})
.catch((err) => reject(err));
});
};
now we can import { isSignedIn } from '../actions/auth'; from any of our components and use it like this:
isSignedIn()
.then((res) => {
if (res) {
// user is properly logged in and the login keys are valid and less than 14 days
}
})
////////////////////////////////////////////////////////////////////////////
If you want to use redux
Handling login in redux
In your types.js
//types.js
export const LOGGED_IN = 'LOGGED_IN';
In your redux actions
//loginActions.js
import {
LOGGED_IN,
} from './types';
export function login() {
let dateOfLastLogin = null;
let isLoggedIn = 'false';
AsyncStorage.multiGet(['auth_key', 'dateOfLastLogin'])
.then((res) => {
isLoggedIn = res[0][1];
dateOfLastLogin = parseInt(res[1][1]);
}); //note this works asynchronously so, this may not be a good approach
return {
type: LOGGED_IN,
isLoggedIn,
dateOfLastLogin
};
}
In your loginReducer
//LoginReducer.js
import {
LOGGED_IN
} from '../actions/types';
const initialState = {
userIsLoggedIn: false
};
export function loginReducer(state=initialState, action) {
switch (action.type) {
case LOGGED_IN:
const userKey = action.isLoggedIn;
const lastLoginDate = action.dateOfLastLogin;
const today = new Date().getTime();
const daysElapsed = Math.round(
(today - lastLoginDate) / 86400000
);
let trulyLoggedIn = false;
if (userKey !== null && (daysElapsed < 14)) {
trulyLoggedIn = true;
} else { trulyLoggedIn = false }
return {
userIsLoggedIn: trulyLoggedIn
};
default:
return state;
}
}
In your ./reducers/index.js
//reducers index.js
import { combineReducers } from 'redux';
import { loginReducer } from './LoginReducers';
const rootReducer = combineReducers({
loggedIn: loginReducer
});
export default rootReducer;
In your store where you used redux-thunk, applyMiddleWare. Lets call it configureStore.js
//configureStore.js
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
applyMiddleware(thunk)
);
}
In your App.js
//App.js
import { Provider } from 'react-redux';
import configureStore from './src/store/configureStore'; //where you configured your store
import { YourMainNavigator } from '../src/config/router'; //where your root navigator is
const store = configureStore();
export default class App extends Component<{}> {
render() {
return (
<Provider store={store}>
<YourMainNavigator />
</Provider>
);
}
}
You should know you no longer need the isSignedIn method in your auth.js
Your login method remains the same as outlined above in LoginScreen.
Now you can use redux to check the state of login like this:
import React, {Component} from 'react';
import {connect} from 'react-redux';
class MyComponent extends Component {
someFunction() {
if (this.props.loggedIn) {
//do something
}
}
}
const mapStateToProps = (state) => {
return {
loggedIn: state.loggedIn.userIsLoggedIn
};
}
export default connect(mapStateToProps)(MyComponent);
There should be a better way of using redux to manage login - better than what I outlined here. I think you can also use redux to manage your login state without using AsyncStorage. All you need to do is in your loginScreen, if the login functions returns a response.status == 'ok', you can dispatch an action to redux that logs the user in. In the example above, using asyncstorage you might only need to use redux to check if a user is logged in.
It is recommended that you use an abstraction on top of AsyncStorage instead of AsyncStorage directly for anything more than light usage since it operates globally. Redux-persist is that abstraction that goes on top of AsyncStorage. It provides a better way to store and retrieve more complex data (e.g. redux-persist has persistReducer(), persistStore()).
React native typescript implementation
storage.ts
import AsyncStorage from "#react-native-community/async-storage";
import { createStore, combineReducers } from "redux";
import { persistStore, persistReducer } from "redux-persist";
import exampleReducer from "./example.reducer";
const rootReducer = combineReducers({
example: exampleReducer,
});
const persistConfig = {
key: "root",
storage: AsyncStorage,
whitelist: ["example"],
};
// Middleware: Redux Persist Persisted Reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer);
// Middleware: Redux Persist Persister
let persistor = persistStore(store);
export { store, persistor };
App.tsx
import React from "react";
import { PersistGate } from "redux-persist/es/integration/react";
import { Provider } from "react-redux";
import RootNavigator from "./navigation/RootNavigator";
import { store, persistor } from "./store";
function App() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootNavigator />
</PersistGate>
</Provider>
);
}
export default App;