How to insert data in firebase using expo..? - react-native

I've an issue, actually I want to insert data into firebase using expo from different screen(I'm using google auth in another screen and after completing it I'm going to main screen), it's working also but it is not saving data in which table I want it to store(after google auth, I'm saving data into firebase in 'users')..
// I'm using this code to insert data in first place (while login)
// and I'm also using isUserNew() method and it's working really fine..
onSignIn = googleUser => {
console.log('Google Auth Response', googleUser);
// We need to register an Observer on Firebase Auth to make sure auth is initialized.
var unsubscribe = firebase.auth().onAuthStateChanged(function(firebaseUser) {
unsubscribe();
// Check if we are already signed-in Firebase with the correct user.
if (!this.isUserEqual(googleUser, firebaseUser)) {
// Build Firebase credential with the Google ID token.
var credential = firebase.auth.GoogleAuthProvider.credential(
googleUser.idToken,
googleUser.accessToken
);
// Sign in with credential from the Google user.
firebase.auth().signInAndRetrieveDataWithCredential(credential).then(function(result) {
console.log('user signed in');
if(result.additionalUserInfo.isNewUser){
firebase.database().ref('/users/' + result.user.uid).set({
gmail: result.user.email,
profile_picture: result.additionalUserInfo.profile.picture,
locale: result.additionalUserInfo.profile.locale,
first_name: result.additionalUserInfo.profile.given_name,
last_name: result.additionalUserInfo.profile.family_name,
created_at: Date.now()
}).then(function (snapshot){
// console.log('Snapshot', snapshot);
});
}else{
firebase.database().ref('/users/' + result.user.uid).update({
last_logged_in: Date.now()
});
}
}).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// The email of the user's account used.
var email = error.email;
// The firebase.auth.AuthCredential type that was used.
var credential = error.credential;
// ...
});
} else {
console.log('User already signed-in Firebase.');
}
}.bind(this));
};
// This code is also showing an error that I can't call setState from an //unmounted component.
// :- this function as well update() in firebase is in another screen or page.
async componentDidMount() {
try {
let {status} = await Permissions.getAsync(Permissions.LOCATION);
if(status !== 'granted'){
const {status} = await Permissions.askAsync(Permissions.LOCATION);
}else{
const watchId = navigator.geolocation.watchPosition(
({ coords : {latitude, longitude} }) => this.setState({latitude, longitude}, () => console.log('State:', this.state)),
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 0, maximumAge: 1000, distanceFilter: 1},
);
await AsyncStorage.setItem('LiveFeedId', JSON.stringify(watchId));
}
}
catch(err) {
console.error(error);
}
};
/* when I'm using this code it's saving the data but not in 'users' table in firebase */
firebase.database().ref('users/').update({
latitude: latitude,
longitude: longitude,
});
Can anyone please help me out here, I'm really new to react native..
And I want to update my latitude and longitude from another screen to firebase where I've saved my users details, ex:- 'firebase.database().ref('/users/' + result.user.uid)'..
Thanks

Related

React Native Google Sign In User Birthday Access Problem

I am trying to get user birthday when user is registered with Google Sign In and want to display his/her info in the profile page.
Google Sign In was implemented via firebase.
And then, I went to google developer console and made
Added People Apis and then go to OAuth consent screen
Select External
Added App domain, Authorized domains, Developer contact information
Added birthday scope
Added test users
Save and Back to Dashboard
Birthday info is set as public
The problem is still my test users cannot login to Google. It says "Access Denied. your app did not complete the google verification process. The app is currently being tested. Only approved test users can access the app."
I can only login with my developer account.
And when I logged in, in the console, I can see the birthday scope is added in scopes array. However the birthday info is still not in my user object.
I use "#react-native-google-signin/google-signin": "^6.0.1" package.
Can someone help me please ?
Do I need to verify the domain/owner to be able to see birthday info ?
Or the package does not support this info ?
Why my test users cannot login even though I added them ?
My code is below
export const auth = {
initGoogleSignIn: function () {
GoogleSignin.configure({
scopes: [
'https://www.googleapis.com/auth/user.birthday.read',
'https://www.googleapis.com/auth/user.gender.read',
'https://www.googleapis.com/auth/plus.login',
],
// scopes: ['https://www.googleapis.com/auth/plus.login'],
webClientId: Config.GOOGLE_WEB_CLIENT_ID,
offlineAccess: false,
});
},
};
import auth from '#react-native-firebase/auth';
export const googleLogin = () => {
return async dispatch => {
try {
await GoogleSignin.hasPlayServices({showPlayServicesUpdateDialog: true});
const isSignedIn = await GoogleSignin.isSignedIn();
if (isSignedIn && Platform.OS === 'android') {
await GoogleSignin.revokeAccess();
}
const {idToken} = await GoogleSignin.signIn();
const token = await GoogleSignin.getTokens();
dispatch(handleSocialSignup(COMMON.GOOGLE, token?.accessToken));
// Create a Google credential with the token
const googleCredential = auth.GoogleAuthProvider.credential(idToken);
// Sign-in the user with the credential
const userSignIn = auth().signInWithCredential(googleCredential);
Alert.alert(JSON.stringify(userSignIn));
userSignIn.then(user => Alert.alert(user)).catch(err => console.log(err));
} catch (error) {
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log('Cancelled by user');
} else if (error.code === statusCodes.IN_PROGRESS) {
// operation (e.g. sign in) is in progress already
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
// play services not available or outdated
} else {
Sentry.captureException(error);
Sentry.captureMessage(strings.common.undefinedError);
console.log('some other error happened', error);
dispatch(showSnackbar(strings.common.undefinedError));
}
return false;
}
const [googleUserName, setGoogleUserName] = useState('');
const getGoogleUserName = async () => {
const currentUser = await GoogleSignin.getCurrentUser();
setGoogleUserName(currentUser);
console.log('currentUser', currentUser);
};
useEffect(() => {
getGoogleUserName();
}, []);
console.log('googleUserName', googleUserName);

React Native Facebook User Photos is Denied

I have a react native app and i can login with facebook. However I can't get the users photo. First of all FB hash key is correct and my app is in live mode. I sent the app to APP REVIEW and the photos are always denied by team and they are telling me they can't get the photos of the users. I use "react-native-fbsdk-next": "^4.3.0" and we use our own api url for photos, not using Graph Api of FB. There is [user_photos] as well beside public_profile. Does anyone know the reason for this ? After I login to Facebook, i try to upload photo via FB and it displays a pop up saying " facebook photos permission is denied. This permission allows your app to read photos of Facebook". Why facebook team denies user photo access ? what else should do to make it work ? My login code implementation is below. I could not find anything on Google regarding this kind of issue. Please help
export const facebookLogin = snackBarBottomMargin => {
return async dispatch => {
try {
const result = await LoginManager.logInWithPermissions([
'public_profile',
'user_photos',
]);
if (!result.isCancelled) {
const data = await AccessToken.getCurrentAccessToken();
if (data && data.accessToken) {
await storage.storeData(
PREFERENCES.FB_ACCESS_TOKEN,
JSON.stringify(data),
);
return data;
} else {
console.log('Facebook result fetch token error cancelled');
return false;
}
} else {
console.log('Login cancelled');
return false;
}
} catch (error) {
dispatch(
showSnackbar(strings.login.facebookLoginError, snackBarBottomMargin),
);
return false;
}
};
};
export function handleFetchFBPhotos(accessToken, after) {
return async dispatch => {
function onSuccess(success) {
dispatch(fetchMediaSuccess(success));
console.log('success', success);
return success;
}
function onError(error) {
dispatch(fetchMediaFailed(error));
console.log('error', error);
return error;
}
try {
dispatch(fetchMediaRequest(true));
const config = {
baseURL: Config.FACEBOOK_BASE_URL,
params: {
type: 'uploaded',
fields: 'images',
after,
},
headers: {Authorization: `Bearer ${accessToken}`},
};
const response = await axios.get(FACEBOOK_PHOTOS, config);
if (response.data && response.data.data) {
console.log('response.data', response.data);
console.log('response.data.data', response.data.data);
console.log('onSuccess(response.data)', onSuccess(response.data));
return onSuccess(response.data);
}
} catch (error) {
const errorObj = getErrorResponse(
error,
Config.FACEBOOK_BASE_URL + FACEBOOK_PHOTOS,
);
console.log('onError(errorObj.message)', onError(errorObj.message));
return onError(errorObj.message);
}
};
}

How to get FB Access Token with Expo

I'm building app where i need to make Facebook Graph API requests in many places. But i dont know how to retrieve access token and then make Graph API request.
I'm using Expo, React Native and Firebase. I would like to do it without installing Xcode and/or Android Studio.
Login is working fine. My code is below:
async loginWithFacebook() {
try {
const {
type,
token,
expires,
permissions,
declinedPermissions,
} = await Expo.Facebook.logInWithReadPermissionsAsync('<APP_ID', {
permissions: ['email', 'public_profile'],
});
if (type === 'success') {
const credential = f.auth.FacebookAuthProvider.credential(token)
f.auth().signInAndRetrieveDataWithCredential(credential).catch((error) => {
console.log(error)
})
var that = this;
const response = await fetch(`https://graph.facebook.com/me/?fields=id,name&access_token=${token}`);
const userInfo = await response.json();
this.setState({userInfo});
this.setState({
dataSource: userInfo.data,
isLoading: false,
});
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
Can someone help me and give me some tips how i can use access token everywhere in my app?
Thank you in advance
Getting the token and saving it into AsyncStorage
Well the code that you have written is basically correct. You have successfully got the access token. It comes back to you when you make the Expo.Facebook.logInWithReadPermissionsAsync request. Once you have it you could then store it in Redux or AsyncStorage to be used at a later date.
logIn = async () => {
let appID = '123456789012345' // <- you'll need to add your own appID here
try {
const {
type,
token, // <- this is your access token
expires,
permissions,
declinedPermissions,
} = await Expo.Facebook.logInWithReadPermissionsAsync(appID, { permissions: ['public_profile', 'email'], });
if (type === 'success') {
// Get the user's name using Facebook's Graph API
const response = await fetch(`https://graph.facebook.com/me/?fields=id,name&access_token=${token}`); //<- use the token you got in your request
const userInfo = await response.json();
alert(userInfo.name);
// you could now save the token in AsyncStorage, Redux or leave it in state
await AsyncStorage.setItem('token', token); // <- save the token in AsyncStorage for later use
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
app.json
Also remember to add the following to your app.json, obviously replacing the values with your own. You get these by registering your app with Facebook, you can see more about that here https://docs.expo.io/versions/latest/sdk/facebook/#registering-your-app-with-facebook
{
"expo": {
"facebookScheme": "fb123456789012345",
"facebookAppId": "123456789012345", // <- this is the same appID that you require above when making your initial request.
"facebookDisplayName": "you_re_facebook_app_name",
...
}
}
Getting token from AsyncStorage
Then if you wanted to make another request at a later time you could have a function similar to this where you get the token out of AsyncStorage and then use it to make your request.
makeGraphRequest = async () => {
try {
let token = await AsyncStorage.getItem('token'); // <- get the token from AsyncStorage
const response = await fetch(`https://graph.facebook.com/me/?fields=id,name&access_token=${token}`); // <- use the token for making the graphQL request
const userInfo = await response.json();
alert(userInfo.name)
} catch (err) {
alert(err.message)
}
}
Snack
I would make a snack to show you this working however, snacks do not allow editing of the app.json file (as far as I can tell). So here is something that you could replace your App.js with and then if you added your appIDs etc to the app.json it should work.
import React from 'react';
import { AsyncStorage, Text, View, StyleSheet, SafeAreaView, Button } from 'react-native';
export default class App extends React.Component {
logIn = async () => {
let appID = '123456789012345' // <- you'll need to add your own appID here
try {
const {
type,
token, // <- this is your access token
expires,
permissions,
declinedPermissions,
} = await Expo.Facebook.logInWithReadPermissionsAsync(appID, {
permissions: ['public_profile', 'email'],
});
if (type === 'success') {
// Get the user's name using Facebook's Graph API
const response = await fetch(`https://graph.facebook.com/me/?fields=id,name&access_token=${token}`); //<- use the token you got in your request
const userInfo = await response.json();
console.log(userInfo);
alert(userInfo.name);
// you could now save the token in AsyncStorage, Redux or leave it in state
await AsyncStorage.setItem('token', token); // <- save the token in AsyncStorage for later use
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
makeGraphRequest = async () => {
try {
let token = await AsyncStorage.getItem('token');
// Get the user's name using Facebook's Graph API
const response = await fetch(`https://graph.facebook.com/me/?fields=id,name&access_token=${token}`);
const userInfo = await response.json();
alert(userInfo.name)
} catch (err) {
alert(err.message)
}
}
render() {
return (
<View style={styles.container}>
<Button title={'Sign in to Facebook'} onPress={this.logIn} />
<Button title={'Make GraphQL Request'} onPress={this.makeGraphRequest} />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'white'
}
});

react-native-linkdin-login is not working in ios?

I am using react-native-linkdin-login library to support linkding sigin in my application.It is working properly in android but in iOS it always ask to download an application rather than application already exist in device and redirect to the APP store. When I open and login to linkdin account, I can't come back to my react-native application, with user profile details.
Give me any suggestion as soon as possible.
async componentWillMount() {
LinkedinLogin.init(
[
'r_emailaddress',
'r_basicprofile'
]
);
}
async handleLinkedinLogin(){
LinkedinLogin.login().then((user) => {
alert("linkdin");
this.setState({ user : user });
this.getUserProfile();
}).catch((e) => {
var err = JSON.parse(e.description);
alert("ERROR: " + err.errorMessage);
alert('Error', e);
});
return true;
}
getUserProfile(user) {
LinkedinLogin.getProfile().then((data) => {
const userdata = Object.assign({}, this.state.user, data);
this.setState({ user: userdata });
const Email = userdata.emailAddress;
const Fullname = userdata.firstName+' '+userdata.lastName;
const SocialAppId = userdata.id;
const SignupType = 'Linkedin';
alert("Please wait....")
this.socialLogin(Fullname,Email,'null',SignupType);
}).catch((e) => {
alert(e);
});
}

React Native - Download image from Facebook profile?

I'm using React Native FBSDK to integrate my app's user profiles with their Facebook. I'm looking for a way to allow the user to download images from their Facebook to my app. Similar to how this functions in Tinder.
To do that you need to do a graph request on Facebook to get more informations about a specific user.
That look something like that :
//first you need to sign in your user and then ...
let result = await this.FBGraphRequest('id, email, picture.type(large), last_name, first_name');
FBGraphRequest = async (fields) => {
const accessData = await AccessToken.getCurrentAccessToken();
this.saveToken(accessData["accessToken"], "facebook");
// Create a graph request asking for user information
return new Promise((resolve, reject) => {
const infoRequest = new GraphRequest('/me', {
accessToken: accessData.accessToken,
parameters: {
fields: {
string: fields
}
}
},
(error, result) => {
if (error) {
console.log('Error fetching data: ' + error.toString());
reject(error);
} else {
resolve(result);
}
});
new GraphRequestManager().addRequest(infoRequest).start();
});
};
To have much informations I redirect you to this great medium post.