diff --git a/README.md b/README.md index 56e4a21..7accd90 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Today's community use mobile phones to make their life easier, and community-bas - Use [this link](https://cloud.google.com/maps-platform/) to **generate Google Map Api key** for the map view in G-social. This is not necessary. You can use the given api key. But it is not guaranteed that the given key will always work. It is better to have your own key. Enable all maps, routes, places in your key. -- Now you need a **Facebook app id** if you want to enable Facebook login for Go-social. Use [this link](https://developers.facebook.com/) for that and make sure to enable both email/password and Facebook sign-in method in Firebase. +- Now you need a **Facebook app id** & **Facebook Client Token** if you want to enable Facebook login for Go-social. Use [this link](https://developers.facebook.com/) for that and make sure to enable both email/password and Facebook sign-in method in Firebase. So place your Firebase details and Google map API key in **config.example.js** file and **rename it** to **config.js**. @@ -42,14 +42,19 @@ So place your Firebase details and Google map API key in **config.example.js** f 1. Find the file name `AndroidManifest.xml` which is located in `android/app/src/main` path. Place your **Google map API key** in there. - > Ex : +``` - android:name="com.google.android.geo.API_KEY" - android:value=**"AIzaSyDmwJddIPTcALyZtj7p9mFFlkMvpMkati8"**/> +1. Find the file name as `strings.xml` located in `android/app/src/main/res/values`. Place your **Facebook app id** & **Facebook Client Token** in there. -1. Find the file name as `strings.xml` located in `android/app/src/main/res/values`. Place your **Facebook app id** in there. - - > Ex: **2349388348405699** +```sh +2349388348405699 +fb1234 +PLACE_YOUR_CLIENT_TOKEN_HERE +``` So now you are ready to run Go-social. diff --git a/android/app/build.gradle b/android/app/build.gradle index 0845c3b..59e3429 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -152,6 +152,7 @@ dependencies { // The version of react-native is set by the React Native Gradle Plugin implementation("com.facebook.react:react-android") implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0") + implementation 'com.facebook.android:facebook-android-sdk:11.1.0' // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:31.2.3') diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c57e0f5..0dcae1a 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,10 +1,12 @@ - + + + + + + + + + + + + + diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 284c98a..b001aeb 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,4 +1,6 @@ Go_social - 2349388348405699 + 222891166977339 + fb1234 + PLACE_YOUR_CLIENT_TOKEN_HERE diff --git a/app/constants/auth.js b/app/constants/auth.js new file mode 100644 index 0000000..e40cea2 --- /dev/null +++ b/app/constants/auth.js @@ -0,0 +1,5 @@ +export const fetchUserFbData = (token) => { + return fetch( + `https://graph.facebook.com/v2.8/me?fields=id,first_name,last_name,email,birthday&access_token=${token}` + ) +} \ No newline at end of file diff --git a/app/screens/LoginScreen/loginScreen.js b/app/screens/LoginScreen/loginScreen.js index 319f953..cc1281b 100644 --- a/app/screens/LoginScreen/loginScreen.js +++ b/app/screens/LoginScreen/loginScreen.js @@ -9,23 +9,25 @@ import { KeyboardAvoidingView, ScrollView, } from "react-native"; -import { AccessToken, LoginManager } from "react-native-fbsdk"; -import { f, auth } from "../../../config/config.js"; +import { LoginManager, AccessToken } from "react-native-fbsdk-next"; +import { app, auth, database } from "../../../config/config.js"; +import {FacebookAuthProvider} from "firebase/auth"; import * as EmailValidator from "email-validator"; -import styles from "./style"; import { SocialIcon } from "react-native-elements"; +import styles from "./style"; +import { fetchUserFbData } from "../../constants/auth.js"; + export default class LoginScreen extends Component { constructor(props) { super(props); this.state = { email: "", - Password: "", + password: "", }; } componentDidMount() { var that = this; - auth.onAuthStateChanged(function (user) { if (user) { that.redirectUser(); @@ -33,108 +35,74 @@ export default class LoginScreen extends Component { }); } - login() { - let email = this.state.email; - let password = this.state.Password; - - let { navigate } = this.props.navigation; - - auth - .signInWithEmailAndPassword(email, password) - .then(function (data) { - navigate("App"); - }) - .catch(function (error) { - var errorMessage = error.message; - alert(errorMessage.toString()); - }); - } - redirectUser() { const { navigate } = this.props.navigation; navigate("App"); } - _signInAsync = async () => { - if (EmailValidator.validate(this.state.email) === true) { - if (this.state.Pasword != "") { + // Validate the user's email and password + async _signInAsync() { + switch(true) { + case !EmailValidator.validate(this.state.email): + alert("Please enter a valid email!"); + break; + case this.state.password === "": + alert("Enter your password!"); + break; + default: this.login(); - } else { - alert("Enter the password"); - } - } else { - alert("Please enter A Valid Email"); + break; } - }; - - onPressLogin() { - LoginManager.logInWithReadPermissions(["public_profile", "email"]).then( - result => this._handleCallBack(result), - function (error) { - alert("Login fail with error: " + error); - } - ); } - _handleCallBack(result) { - let _this = this; - if (result.isCancelled) { - alert("Login cancelled"); - } else { - AccessToken.getCurrentAccessToken().then(data => { - const token = data.accessToken; - fetch( - "https://graph.facebook.com/v2.8/me?fields=id,first_name,last_name,gender,birthday&access_token=" + - token - ) - .then(response => response.json()) - .then(json => { - const imageSize = 120; - const facebookID = json.id; - const fbImage = `https://graph.facebook.com/${facebookID}/picture?height=${imageSize}`; - this.authenticate(data.accessToken).then(function (result) { - const { uid } = result; - _this.createUser(uid, json, token, fbImage); - }); - }) - .catch(function (err) { - console.log(err); - }); - }); + // Signin with email and password + async login() { + try { + const email = this.state.email; + const password = this.state.password; + + const res = await auth.signInWithEmailAndPassword(email, password); + } catch (error) { + alert(error.message.toString()); } } - authenticate = token => { - const provider = auth.FacebookAuthProvider; - const credential = provider.credential(token); - let ret = auth.signInWithCredential(credential); - return ret; - }; - - createUser = (uid, userData, token, dp) => { - const defaults = { - uid, - token, - dp, - ageRange: [20, 30], - }; - f.database() - .ref("users") - .child(uid) - .update({ ...userData, ...defaults }); - }; - - _signInAsync = async () => { - if (EmailValidator.validate(this.state.email) === true) { - if (this.state.Pasword != "") { - this.login(); - } else { - alert("Enter the password"); + // Signin user with facebook account + async _fbSignInAsync() { + try { + const result = await LoginManager.logInWithPermissions(["public_profile", "email"]); + if (!result.isCancelled) { + // Get the user's access token + const data = await AccessToken.getCurrentAccessToken(); + + // Use the user's access token to authenticate with Firebase Authentication + const credential = FacebookAuthProvider.credential(data.accessToken); + const { user } = await auth.signInWithCredential(credential); + + const response = await fetchUserFbData(data.accessToken) + const userData = await response.json(); + + const photoURL = `https://graph.facebook.com/${userData.id}/picture?height=120`; + this.createUser(user.uid, userData, data.accessToken, photoURL); } - } else { - alert("Please enter A Valid Email"); + } catch (error) { + alert(error.message.toString()); } - }; + } + + // Create user + async createUser(uid, userData, token, photoURL) { + try { + const defaults = { uid, token, photoURL, Range: [20, 30] }; + await database.ref(`users/${uid}`).set({ ...userData, ...defaults }); + } catch (error) { + alert(error.message.toString()); + } + } + + handleInput(input, text) { + this.setState(prevState => ({ ...prevState, [input]: text })); + } render() { return ( @@ -151,7 +119,7 @@ export default class LoginScreen extends Component { keyboardType="email-address" placeholderTextColor="rgba(255,255,255,0.7)" style={styles.input} - onChangeText={text => this.setState({ email: text })} + onChangeText={text => this.handleInput("email", text)} ref={input => { this.textInput = input; }} @@ -161,14 +129,14 @@ export default class LoginScreen extends Component { secureTextEntry={true} placeholderTextColor="rgba(255,255,255,0.7)" style={styles.input} - onChangeText={text => this.setState({ Password: text })} + onChangeText={text => this.handleInput("password", text)} ref={input => { this.textInput = input; }} /> - + Sign In @@ -176,9 +144,9 @@ export default class LoginScreen extends Component { Forgot Password? - + this._handleCallBack(result), - function (error) { - alert("Login fail with error: " + error); + // Validate user input for sign up + async _signUpAsync() { + switch (true) { + case (this.state.name === ""): + alert("Please enter your name!"); + break; + case (!EmailValidator.validate(this.state.email)): + alert("Please enter a valid email!"); + break; + case (this.state.password === ""): + alert("Please enter a password!"); + break; + case (this.state.password !== this.state.confirmPassword): + alert("Password and Confirm password must be same"); + break; + default: + this.signup(); + break; + } + } + + // Sign up with email and password + async signup() { + try { + const name = this.state.name; + const email = this.state.email; + const password = this.state.password; + + const { user } = await auth.createUserWithEmailAndPassword(email, password); + await updateProfile(user, { displayName: name }); + } catch (error) { + alert(error.message.toString()); + } + } + + // Signup user with facebook account + async _fbSignUpAsync() { + try { + const result = await LoginManager.logInWithPermissions(["public_profile", "email"]); + if (!result.isCancelled) { + // Get the user's access token + const data = await AccessToken.getCurrentAccessToken(); + + // Use the user's access token to authenticate with Firebase Authentication + const credential = FacebookAuthProvider.credential(data.accessToken); + const { user } = await auth.signInWithCredential(credential); + + const response = await fetchUserFbData(data.accessToken) + const userData = await response.json(); + + const photoURL = `https://graph.facebook.com/${userData.id}/picture?height=120`; + this.createUser(user.uid, userData, data.accessToken, photoURL); } - ); + } catch (error) { + alert(error.message.toString()); + } } - _handleCallBack(result) { - let _this = this; - if (result.isCancelled) { - alert("Login cancelled"); - } else { - AccessToken.getCurrentAccessToken().then(data => { - const token = data.accessToken; - fetch( - "https://graph.facebook.com/v2.8/me?fields=id,first_name,last_name,gender,birthday&access_token=" + - token - ) - .then(response => response.json()) - .then(json => { - const imageSize = 120; - const facebookID = json.id; - const fbImage = `https://graph.facebook.com/${facebookID}/picture?height=${imageSize}`; - this.authenticate(data.accessToken).then(function (result) { - const { uid } = result; - _this.createUser(uid, json, token, fbImage); - }); - }) - .catch(function (err) { - console.log(err); - }); - }); + // Create user + async createUser(uid, userData, token, photoURL) { + try { + const defaults = { uid, token, photoURL, Range: [20, 30] }; + await database.ref(`users/${uid}`).set({ ...userData, ...defaults }); + } catch (error) { + alert(error.message.toString()); } } - authenticate = token => { - const provider = auth.FacebookAuthProvider; - const credential = provider.credential(token); - let ret = auth.signInWithCredential(credential); - return ret; - }; - - createUser = (uid, userData, token, dp) => { - const defaults = { - uid, - token, - dp, - ageRange: [20, 30], - }; - f.database() - .ref("users") - .child(uid) - .update({ ...userData, ...defaults }); - }; + handleInput(input, text) { + this.setState(prevState => ({ ...prevState, [input]: text })); + } render() { return ( @@ -111,32 +128,32 @@ export default class SignUpScreen extends Component { placeholder="Name" placeholderTextColor="rgba(255,255,255,0.7)" style={styles.input} - onChangeText={text => this.setState({ name: text })} + onChangeText={text => this.handleInput("name", text)} /> this.setState({ email: text })} + onChangeText={text => this.handleInput("email", text)} /> this.setState({ Password: text })} + onChangeText={text => this.handleInput("password", text)} /> this.setState({ ConfirmPassword: text })} + onChangeText={text => this.handleInput("confirmPassword", text)} /> - + Sign Up @@ -144,9 +161,9 @@ export default class SignUpScreen extends Component { or - + ); } - register() { - let email = this.state.email; - let name = this.state.name; - let password = this.state.Password; - - const { navigate } = this.props.navigation; - - auth - .createUserWithEmailAndPassword(email, password) - .then(function (data) { - data.user - .updateProfile({ - displayName: name, - }) - .then( - function () { - console.log("Updated User Data.."); - }, - function (error) { - console.log("Error Updating User Data.." + error); - } - ); - alert("Welcome to Go Social!"); - navigate("App"); - }) - .catch(function (error) { - var errorMessage = error.message; - console.log("Error = " + errorMessage); - alert(errorMessage); - }); - } - - signUpAsync = async () => { - if (EmailValidator.validate(this.state.email) === true) { - if (this.state.Password === this.state.ConfirmPassword) { - this.register(); - } else { - alert("password Missmatch"); - } - } else { - alert("Please enter A Valid Email"); - } - }; } diff --git a/config/config.example.js b/config/config.example.js index b5b9722..f2c2cc8 100644 --- a/config/config.example.js +++ b/config/config.example.js @@ -1,19 +1,25 @@ -import firebase from "firebase"; +import firebase from "firebase/compat/app" +import "firebase/compat/auth" +import "firebase/compat/storage"; +import "firebase/compat/database"; -var config = { +const firebaseConfig = { apiKey: "", authDomain: "", databaseURL: "", projectId: "", storageBucket: "", messagingSenderId: "", + appId: "", + measurementId: "", }; -firebase.initializeApp(config); -var MAP_API_KEY = ""; +firebase.initializeApp(firebaseConfig) -export const f = firebase; -export const database = firebase.database(); -export const auth = firebase.auth(); -export const storage = firebase.storage(); -export const MAP_API = MAP_API_KEY; +const app = firebase; +const auth = firebase.auth(); +const storage = firebase.storage(); +const db = firebase.database(); +const MAP_API = ""; + +export { app, auth, storage, db, MAP_API }; diff --git a/package.json b/package.json index 4786d3f..21625a9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "react": "18.2.0", "react-native": "0.71.3", "react-native-elements": "^3.4.3", - "react-native-fbsdk": "^3.0.0", + "react-native-fbsdk-next": "^11.1.0", "react-native-gesture-handler": "^2.9.0", "react-native-google-places-autocomplete": "^2.5.1", "react-native-image-crop-picker": "^0.39.0",