I'm trying to implement the Firebase Auth in my Project, I was able to do it (at least for Email and Password Auth in Firebase) through the REST API from Firebase. However, I need to work with Social Authentication (Facebook and Google, besides Email and Password at least).
I'm using EXPO for my project (that is why I don't have the Folders of iOS or Android).
I have already install Firebase Dependency in my package.json:
I have also initialized Firebase on my App:
FirebaseKeys.js File:
export default {
firebaseConfig: {
apiKey: "[myApi Key]",
authDomain: "alianzafc2021.firebaseapp.com",
databaseURL: "https://alianzafc2021-default-rtdb.firebaseio.com",
projectId: "alianzafc2021",
storageBucket: "alianzafc2021.appspot.com",
messagingSenderId: "[Messaging ID]",
appId: "[App ID]",
measurementId: "[Measurement ID}]"
}
}
App.js: (Where I initialize the Firebase)
import React, { useState } from 'react';
import { createStore, combineReducers, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import ReduxThunk from 'redux-thunk';
import * as Font from 'expo-font';
import * as firebase from 'firebase';
//Firebase Initialize Config
import firebaseConfig from "./constants/FireBaseKeys";
//Navigation
import AppNavigator from "./navigation/AppNavigator";
//import de reducers
import jugadoresReducer from "./store/reducers/jugadores";
import noticiasReducer from "./store/reducers/noticias";
import partidosReducer from "./store/reducers/partido";
import tablaReducer from "./store/reducers/tabla";
import authReducer from "./store/reducers/auth";
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}else {
firebase.app(); // if already initialized, use that one
}
const rootReducer = combineReducers({
jugadores: jugadoresReducer,
noticias: noticiasReducer,
partidos: partidosReducer,
tabla: tablaReducer,
auth: authReducer,
});
const store = createStore(rootReducer,applyMiddleware(ReduxThunk));
//Recibe la Tipografia de numeros
const fetchFonts = () => {
return Font.loadAsync({
'number': require('./assets/fonts/number.ttf'),
});
};
export default function App() {
const [fontLoaded, setFontLoaded] = useState(true);
if (!fontLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={() => {
setFontLoaded(true);
}} />
);
}
return (
<Provider store={store}>
<AppNavigator />
</Provider>
);
}
I also have created the login page without functionality (Just trying to Login which is giving the Error):
import React, {useState,useCallback} from 'react';
import {
View,
Text,
TouchableOpacity,
Image,
Platform,
StyleSheet,
ScrollView
} from 'react-native';
import { useDispatch } from 'react-redux';
import FormInput from '../components/UI/FormInput';
import FormButton from '../components/UI/FormButton';
import SocialButton from '../components/UI/SocialButton';
import * as authActions from '../store/actions/auth';
const LoginScreen = ({navigation}) => {
const [email, setEmail] = useState();
const [password, setPassword] = useState();
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState();
const dispatch = useDispatch();
const LoginHandler = useCallback ( async (email, password) => {
setError(null);
setIsLoading(true);
try {
await dispatch(authActions.login(email,password));
//props.navigation.navigate('Shop');
} catch (err) {
setError(err.message);
setIsLoading(false);
}
}, [dispatch, setEmail, setPassword]);
return (
<ScrollView contentContainerStyle={styles.container}>
<Image
source={require('../assets/alianza-logo.png')}
style={styles.logo}
/>
<Text style={styles.text}>Albo App</Text>
<FormInput
labelValue={email}
onChangeText={(userEmail) => setEmail(userEmail)}
placeholderText="Correo"
iconType="user"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
<FormInput
labelValue={password}
onChangeText={(userPassword) => setPassword(userPassword)}
placeholderText="Contrase?a"
iconType="lock"
secureTextEntry={true}
/>
<FormButton
buttonTitle="Ingresar"
onPress={LoginHandler(email, password)}
/>
<TouchableOpacity style={styles.forgotButton} onPress={() => {}}>
<Text style={styles.navButtonText}>Olvidaste la Contrase?a?</Text>
</TouchableOpacity>
{Platform.OS === 'android' ? (
<View>
<SocialButton
buttonTitle="Ingresa con Facebook"
btnType="facebook"
color="#4867aa"
backgroundColor="#e6eaf4"
onPress={() => {}}
/>
<SocialButton
buttonTitle="Ingresa con Google"
btnType="google"
color="#de4d41"
backgroundColor="#f5e7ea"
onPress={() => {}}
/>
</View>
) : null}
<TouchableOpacity
style={styles.forgotButton}
onPress={() => navigation.navigate('Signup')}>
<Text style={styles.navButtonText}>
Crear una Cuenta
</Text>
</TouchableOpacity>
</ScrollView>
);
};
export default LoginScreen;
const styles = StyleSheet.create({
container: {
justifyContent: 'center',
alignItems: 'center',
padding: 20,
paddingTop: 50,
marginTop: 30
},
logo: {
height: 150,
width: 150,
resizeMode: 'cover',
},
text: {
fontSize: 28,
marginBottom: 10,
color: '#051d5f',
},
navButton: {
marginTop: 15,
},
forgotButton: {
marginVertical: 35,
},
navButtonText: {
fontSize: 18,
fontWeight: '500',
color: '#2e64e5'
},
});
Now my problem is that I'm not able to give the Functionality to save some info upon login on my Reducer (or even reach the login event on my Actions).
Here is my Actions file (I comment out the code which works when using the Rest API to Login I have modified just the login function):
import AsyncStorage from '@react-native-community/async-storage';
import Auth from "firebase/firebase-auth";
//export const SIGNUP = 'SIGNUP';
//export const LOGIN = 'LOGIN';
export const AUTHENTICATE = 'AUTHENTICATE';
export const LOGOUT = 'LOGOUT';
export const SET_DID_TRY_AL = 'SET_DID_TRY_AL';
let timer;
export const setDidTryAL = () => {
return { type: SET_DID_TRY_AL };
};
export const authenticate = (userId, token, expiryTime) => {
return dispatch => {
dispatch(setLogoutTimer(expiryTime));
dispatch({ type: AUTHENTICATE, userId: userId, token: token });
}
}
export const signup = (email, password) => {
return async dispatch => {
const response = await fetch('https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[Here my ID Key]', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
returnSecureToken: true,
})
});
if (!response.ok) {
const errorResData = await response.json();
const errorId = errorResData.error.message;
let message = 'Algo salio mal!';
if (errorId === 'EMAIL_EXISTS') {
message = 'Este Correo ya esta en Uso';
}
throw new Error(message);
}
const resData = await response.json();
console.log(resData.localId);
dispatch(
authenticate(
resData.localId,
resData.idToken,
parseInt(resData.expiresIn) * 1000
)
);
const expirationDate = new Date(new Date().getTime() + parseInt(resData.expiresIn) * 1000);
saveDataToStorage(resData.idToken, resData.localId, expirationDate);
};
};
export const login = (email, password) => {
return async dispatch => {
await firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then(resData => {
console.log(resData);
dispatch(
authenticate(
resData.localId,
resData.idToken,
parseInt(resData.expiresIn) * 1000,
)
)
const expirationDate = new Date(new Date().getTime() + parseInt(resData.expiresIn) * 1000);
saveDataToStorage(resData.idToken, resData.localId, expirationDate);
})
.catch(err => { console.log(err) });
}
// return async dispatch => {
// const response = await fetch('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[Here my ID Key]', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json',
// },
// body: JSON.stringify({
// email: email,
// password: password,
// returnSecureToken: true,
// })
// });
// if (!response.ok) {
// const errorResData = await response.json();
// const errorId = errorResData.error.message;
// let message = 'Algo salio mal!';
// if (errorId === 'EMAIL_NOT_FOUND') {
// message = 'Este Correo no esta en Uso';
// } else if (errorId === 'INVALID_PASSWORD') {
// message = 'Esta Contrase?a esta Equivocada.'
// }
// throw new Error(message);
// }
// const resData = await response.json();
// console.log(resData);
// dispatch(
// authenticate(
// resData.localId,
// resData.idToken,
// parseInt(resData.expiresIn) * 1000,
// )
// );
// const expirationDate = new Date(new Date().getTime() + parseInt(resData.expiresIn) * 1000);
// saveDataToStorage(resData.idToken, resData.localId, expirationDate);
// };
};
export const logout = () => {
clearLogoutTimer();
AsyncStorage.removeItem('userData');
return { type: LOGOUT };
};
const clearLogoutTimer = () => {
if (timer) {