Error code 16 "CANCELLED" in react-native-google-sign-in - javascript

I am trying to implement google sign in on my app and every thing running well , it ask me to choose account on press of sign in button but it response it send me code 16 "CANCELLED" error.
I've installed library by npm install react-native-google-sign-in.
Then I linked it. I created a new project on firebase and download google-services.json from there and paste it in android/app. Also generated release SHA1 and add in firebase project.
componentDidMount() {
GoogleSignin.configure({
//It is mandatory to call this method before attempting to call signIn()
scopes: ['https://www.googleapis.com/auth/drive.readonly'],
// Repleace with your webClientId generated from Firebase console
webClientId:
'my client id',
});
}
Google sign in button and action
<TouchableOpacity
onPress={() => _signIn()}
style={{height:50,width:50,borderRadius:50}}
>
<Image
style={{height:50,width:50}}
resizeMode='contain'
source={ImagePath.GOOGLE_ICON}
/>
</TouchableOpacity>
_signIn = async () => {
//Prompts a modal to let the user sign in into your application.
try {
await GoogleSignin.hasPlayServices({
//Check if device has Google Play Services installed.
//Always resolves to true on iOS.
showPlayServicesUpdateDialog: true,
});
const userInfo = await GoogleSignin.signIn();
alert(JSON.stringify(userInfo))
console.log('User Info --> ', userInfo);
this.setState({ userInfo: userInfo });
} catch (error) {
console.log('Message', error.message);
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
console.log('User Cancelled the Login Flow');
} else if (error.code === statusCodes.IN_PROGRESS) {
console.log('Signing In');
} else if (error.code === statusCodes.PLAY_SERVICES_NOT_AVAILABLE) {
console.log('Play Services Not Available or Outdated');
} else {
alert(JSON.stringify(error))
console.log('Some Other Error Happened',error);
}
}
};
These are my signing config
release {
if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
storeFile file(MYAPP_RELEASE_STORE_FILE)
storePassword MYAPP_RELEASE_STORE_PASSWORD
keyAlias MYAPP_RELEASE_KEY_ALIAS
keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
I expect successful google sign in and user data in response. Any kind of help will be appreciated.Thank you

The fix to this is to add SHA1 to the firebase.
If you are testing for debug build then add debug SHA1 and for release build use release SHA1.
After adding SHA1 certificate fingerprints to the firebase.
Download and add the firebase google-services.json file to /android/app/
You can create a debug key by below command
cd android
gradlew signingReport
OR
cd android && ./gradlew signingReport
Reference link

Please share your AndroidManifest.xml file. Please check whether you have added any launch mode in manifest. If so please remove.

Related

Firebase - sending verifyEmail emails from local or production environment domains

I am trying to configure my firebase settings to that I can send the verifyEmail email from either my development or production environment.
I have a .env file with two settings in it as follows:
REACT_APP_PROD_CONFIRMATION_EMAIL_REDIRECT=https://example.com
REACT_APP_DEV_CONFIRMATION_EMAIL_REDIRECT=http://localhost:3000
Then in my firebase config file I have:
doSendEmailVerification = () =>
this.auth.currentUser.sendEmailVerification({
url: process.env.NODE_ENV === 'production' ? process.env.REACT_APP_PROD_CONFIRMATION_EMAIL_REDIRECT : process.env.REACT_APP_DEV_CONFIRMATION_EMAIL_REDIRECT,
});
This works fine when I'm testing in the development environment.
When I deploy the release and try to test it in production - the email does not send.
Both firebase accounts are configured the same way to send the email.
No error message is generated and the step in my submit handler just gets skipped.
My submit handler has:
this.props.firebase
.doCreateUserWithEmailAndPassword(values.email, values.password)
.then(authUser => {
return this.props.firebase.user(authUser.user.uid).set(
{
name: values.name,
email: values.email,
createdAt: new Date()
},
{ merge: true },
);
})
.then(() => {
return this.props.firebase.doSendEmailVerification();
})
.then(() => {
this.setState({ ...initialValues });
this.props.history.push(ROUTES.DASHBOARD);
You have to whitelist your domains in the Authentication section of firebase for this to work. I've seen several posts on here that say the whitelisting step is no longer required - but for me, it is.

cant access camera roll in photos react native

I want to access the phone camera roll photos, in React-native by this code:
_handleButtonPress = () => {
CameraRoll.getPhotos({
first: 20,
assetType: 'Photos',
})
.then(r => {
this.setState({ photos: r.edges });
})
.catch((err) => {
alert(err)
});
};
but i get this Error in alert:
could not get photos need: read_external_storage permission
As mentioned in the Google Docs, if the device is running Android 6.0 (API level 23) or higher, and the app's targetSdkVersion is 23 or higher, the user isn't notified of any app permissions at install time.
Therefore you must ask the user to grant the dangerous permissions at runtime
Here's a list of Dangerous Permissions.
You can enable the permissions in React Native as
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
{
'title': 'Access Storage',
'message': 'Access Storage for the pictures'
}
)
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("You can use read from the storage")
} else {
console.log("Storage permission denied")
}
} catch (err) {
console.warn(err)
}
Check here for more details
i added this code in AndroidManifest located at(( Example/android/app/src/main/AndroidManifest.xml)):
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
then i confirmed app permissions in android(and i dont know how to do it at run time) and problem solved.

`result.isCancelled` + `result.postId` always undefined after cancellation via ShareDialog on Android

I am attempting to utilize the ShareDialog export from the 'react-native-fbsdk' library.
Our implementation (shown below) works perfectly well when the user doesn't have Facebook installed on their device and when they successfully share their photo.
However, when the user begins to share and discards the Facebook window, result.isCancelled is only captured on iOS. result.postId isn't populated on either iOS and Android.
Is there something that needs to be done in order for result.isCancelled to be populated on Android and/or result.postId to be populated on either platform?
ShareDialog.canShow(shareContent).then(
(canShow) => {
if (canShow) {
return ShareDialog.show(shareContent);
} else {
return false;
}
},
).then(
(result) => {
if (!result) {
Alert.alert('Error', 'You must have Facebook installed on this device in order to share this post')
} else if (result.isCancelled) {
Alert.alert('Cancelled', 'Share cancelled');
} else {
Alert.alert('Success!', 'Share successful');
}
},
(error) => {
Alert.alert(`Share fail with error: ${error}`);
},
)

Expo: "auth/operation-not-supported-in-this-enviroment"

I develop a react-native (expo) mobile app and try to sign in with a google account to firebase, but I get an error:
"auth/operation-not-supported-in-this-enviroment. This operation is not supported in the enviroment this application is running on. "location.protocol" must be http, https or chrome-extension and web storage must be enabled"
Code:
loginGoogle() {
var provider = new firebase.auth.GoogleAuthProvider();
provider.addScope('profile');
provider.addScope('email');
firebase.auth().signInWithPopup(provider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
return true;
}).catch(function(error) {
alert(error.code + '\n' +
error.message + '\n' +
error.email + '\n' +
error.credential);
return false;
});
}
signInWithPopup is not supported in react-native. You will need to use a third party OAuth library to get the OAuth ID token or access token and then sign in with Firebase:
const cred = firebase.auth.GoogleAuthProvider.credential(googleIdToken, googleAccessToken);
firebase.auth().signInWithCredential(cred)
.then((result) => {
// User signed in.
})
.catch((error) => {
// Error occurred.
});
Firebase does not support signInWithPopup in a React Native environment.
You can view a full list of supported environments on this page.
You can also submit a feature request for extended Firebase support for React Native here.
If you are using expo bare workflow or simple React native cli (or in simple words which contain android and ios folder) then simply use "React Native Firebase" library.
Here is the link https://rnfirebase.io/
But if you are using expo managed workflow(which donot contain android and ios folder ) then you have to follow below steps .
1.setup google developer account
use this guide to setup : https://docs.expo.dev/versions/latest/sdk/google/
Note that: use host.exp.exponent as the package name.
Another problem you may face in this step is generation of hash,which I also faced,the reason for that error is java dev kit(JDK) is not install ,so do install it before proceeding to this step.
2.Setup Firebase account
Simply setup firebase project as you set before, enable google sign in service
but this time the only change is you have to add client ID of your google developer account in (safest client id field) which will popup once you click on edit Google signin in firebase
look like this
3.Coding Part
import * as Google from 'expo-google-app-auth'; //imported from expo package
import {
GoogleAuthProvider,getAuth
} from 'firebase/auth';
import { initializeApp } from "firebase/app";
import { firebaseconfig } from '[your firebase credentials]';
const app=intitializeApp(firebaseconfig)
const auth=getAuth(app);
async function signInWithGoogleAsync() {
try {
const result = await Google.logInAsync({
androidClientId: 'cliend id from google dev console',
iosClientId: 'client id from google dev console for ios app(if you setup)',
scopes: ['profile', 'email'],
});
if (result.type === 'success') {
console.log(result)
const credential = GoogleAuthProvider.credential(result.idToken, result.accessToken);
// Sign in with credential from the Facebook user.
signInWithCredential(auth, credential)
.then(async result => {
console.log(result)
})
.catch(error => { console.log(error) });
return result.accessToken;
} else {
console.log("cancelled by user")
return { cancelled: true };
}
} catch (e) {
console.log(e);
return { error: true };
}//
}

How to change email in firebase auth?

I am trying to change/update a user's email address using :
firebase.auth().changeEmail({oldEmail, newEmail, password}, cb)
But I am getting ...changeEmail is not a function error. I found the reference here from the old firebase docu.
So how to I do it in the 3.x version? Because I cant find a reference in the new documentation.
You're looking for the updateEmail() method on the firebase.User object: https://firebase.google.com/docs/reference/js/firebase.User#updateEmail
Since this is on the user object, your user will already have to be signed in. Hence it only requires the password.
Simple usage:
firebase.auth()
.signInWithEmailAndPassword('you#domain.example', 'correcthorsebatterystaple')
.then(function(userCredential) {
userCredential.user.updateEmail('newyou#domain.example')
})
If someone is looking for updating a user's email via Firebase Admin, it's documented over here and can be performed with:
admin.auth().updateUser(uid, {
email: "modifiedUser#example.com"
});
FOR FIREBASE V9 (modular) USERS:
The accepted answer will not apply to you. Instead, you can do this, i.e., import { updateEmail } and use it like any other import. The following code was copy/pasted directly from the fb docs at https://firebase.google.com/docs/auth/web/manage-users
Happy coding!
import { getAuth, updateEmail } from "firebase/auth";
const auth = getAuth();
updateEmail(auth.currentUser, "user#example.com").then(() => {
// Email updated!
// ...
}).catch((error) => {
// An error occurred
// ...
});
You can do this directly with AngularFire2, you just need to add "currentUser" to your path.
this.af.auth.currentUser.updateEmail(email)
.then(() => {
...
});
You will also need to reauthenticate the login prior to calling this as Firebase requires a fresh authentication to perform certain account functions such as deleting the account, changing the email or the password.
For the project I just implemented this on, I just included the login as part of the change password/email forms and then called "signInWithEmailAndPassword" just prior to the "updateEmail" call.
To update the password just do the following:
this.af.auth.currentUser.updatePassword(password)
.then(() => {
...
});
updateEmail needs to happen right after sign in due to email being a security sensitive info
Example for Kotlin
// need to sign user in immediately before updating the email
auth.signInWithEmailAndPassword("currentEmail","currentPassword")
.addOnCompleteListener(this) { task ->
if (task.isSuccessful) {
// Sign in success now update email
auth.currentUser!!.updateEmail(newEmail)
.addOnCompleteListener{ task ->
if (task.isSuccessful) {
// email update completed
}else{
// email update failed
}
}
} else {
// sign in failed
}
}
async updateEmail() {
const auth = firebase.auth();
try {
const usercred = await auth.currentUser.updateEmail(this.email.value);
console.log('Email updated!!')
} catch(err) {
console.log(err)
}
}
You can use this to update email with Firebase.
Firebase v9:
const changeEmail = (userInput) => {
const { newEmail, pass } = userInput
signInWithEmailAndPassword(auth, oldEmail, pass)
.then(cred => updateEmail(cred.user, newEmail))
}

Categories