React Native - Download image from Facebook profile? - react-native

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.

Related

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 insert data in firebase using expo..?

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

react-native facebook logout

I'm struggling to setup a logout action in my app, considering the User has logged in through Facebook provider (react-native-fbsdk). What is the proper way to setup a logout? So, when Users get back to my App and try to login, email and password should be requested again. pls help
To login I'm using:
LoginManager.logInWithReadPermissions(['public_profile', 'email']);
I have tried to call LoginManager.logOut(), LoginManager.setLoginBehavior('I have tried all types'), but did not revoke permissions.
I've also tried to call GraphRequest as per code below but I didn't get the desired result.
logoutFacebook = () => {
AccessToken.getCurrentAccessToken()
.then(data => {
return data.accessToken.toString();
})
.then(accessToken => {
const logout = new GraphRequest(
'me/permissions/',
{
accessToken,
httpMethod: 'DELETE'
},
(error, result) => {
if (error) {
console.log(`'Error fetching data: '${error.toString()}`);
} else {
console.log(result);
LoginManager.logOut();
}
}
);
new GraphRequestManager().addRequest(logout).start();
})
.catch(error => {
console.log(error);
});
}

Display profile picture with expo

I am new to React native and expo and I'm trying to handle the user's profile (edit the profile, profile picture, etc...).
I managed to successfully retrieve the user's info from the API and send the changes like the username or password to it but I can't do it for the profile picture.
I've already tried with axios (what I use to communicate to the API):
async componentDidMount() {
const token = await this.getToken();
const AuthStr = 'Bearer '.concat(token);
await axios.get('https://....jpg', { headers: { Authorization: AuthStr } })
.then(res => {
console.log('RESPONSE: ', res.data);
})
.catch((error) => {
console.log('error ' + error);
});
}
But it returns me error 500
Then I tried with the FileSystem from Expo:
let download = FileSystem.createDownloadResumable('https://...jpg',
FileSystem.documentDirectory + 'profile.jpg',
{ headers: { Authorization: AuthStr } },
null,
null);
try {
const { uri } = await download.downloadAsync();
console.log('Finished downloading to ', uri);
this.setState({
pic: uri,
});
} catch (e) {
console.error(e);
}
let info = await FileSystem.getInfoAsync(this.state.pic, null);
console.log(info);
The log says the file is downloaded and the path is something like this:
file:///var/mobile/Containers/Data/Application/20CF6F63-E14D-4C14-9078-EEAF50A37DE1/Documents/ExponentExperienceData/%2540anonymous%app/profile.jpg
The getInfoAsync() returns true, meanings that the image exists in the filesystem. When I try to render it with
<Image source={{uri: this.state.pic}}/>
It displays nothing. What do I do wrong ?
the temporary solution is to move the image to the gallery
let { uri } = await FileSystem.downloadAsync(this.props.item.imgUrl, FileSystem.cacheDirectory + ${this.props.item}.jpg);
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (status === 'granted') {
CameraRoll.saveToCameraRoll(uri).then((uriGallery) => {
//here you have the url of the gallery to be able to use it
});
}
This is the link I referred to in writing the answer.

How to store facebook token in AsyncStorage React Native(Expo)

I am using Expo to Login User with Facebook, I am receiving token with Graph Api but when I try to add the token in Async Storage it is not working.
Please see the code below:
async logIn() {
try {
const {
type,
token,
} = await Facebook.logInWithReadPermissionsAsync('<APP_ID>', {
permissions: ['public_profile'],
});
if (type === 'success') {
// Get the user's name using Facebook's Graph API
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => AsyncStorage.setItem('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
} else {
// type === 'cancel'
}
} catch ({ message }) {
alert(`Facebook Login Error: ${message}`);
}
}
I am receiving the token when I console it
fetch(`https://graph.facebook.com/me?access_token=${token}`)
.then((res) => res.json())
.then((tokenKey) => console.log('userToken',tokenKey))
.then(() => this.props.navigation.navigate('App'))
Please help, I am new to react native and asynchronous programming in JavaScript. TIA :)
Try this if you want to get item from AsyncStorage
AsyncStorage.getItem('userToken', (error, result) => {
if (result) {
//result
}
else {
//error
}
});
Are you getting token from AsyncStorage with getItem?
AsyncStorage.getItem('userToken').then((token) => {
this.setState({hasToken: token !== null,localToken : token})
});
Sorry folks the problem was from my side, I was trying to store an object directly into Async Storage, whereas Async Storage only accepts values in String format. I used
.then((tokenKey) => AsyncStorage.setItem('userToken',JSON.stringify(tokenKey)))
and it fixed the problem,Thanks all for your help