I am trying to integrate google ads to my react native app, so I followed everything from the official docs https://rnfirebase.io/ and I managed to display google ads.
but when it comes to European User Consent I cant display the Google-rendered consent because the result of the method AdsConsentInfo isRequestLocationInEeaOrUnknown is always false even I whitelist my device an set a debug location :
async componentDidMount(){
AdsConsent.addTestDevices(['MY_DEVICE_ID'])
const consentInfo = await AdsConsent.requestInfoUpdate(['pub-XXXXXX']);
await AdsConsent.setDebugGeography(AdsConsentDebugGeography.EEA);
if (
consentInfo.isRequestLocationInEeaOrUnknown &&
consentInfo.status === AdsConsentStatus.UNKNOWN
) {
const formResult = await AdsConsent.showForm({
privacyPolicy: 'https://invertase.io/privacy-policy',
withPersonalizedAds: false,
withNonPersonalizedAds: true,
withAdFree: false,
});
}
}
try and use, use react-native-ads-consent together with firebase ads consent for instance try setting the debug geography with react-native-ads-consent and check location and display the consent form using react-native-firebase ads consent
Place the code block inside a try catch and use a vpn and set the location to any European Country then you will get isRequestLocationInEeaOrUnknown: true
async componentDidMount () {
try {
const consentInfo = await AdsConsent.requestInfoUpdate([
'pub-xxxxxx',
]);
await AdsConsent.setDebugGeography(AdsConsentDebugGeography.EEA);
if (
consentInfo.isRequestLocationInEeaOrUnknown &&
consentInfo.status === AdsConsentStatus.UNKNOWN
) {
const formResult = await AdsConsent.showForm({
privacyPolicy: 'https://www.google.com/privacy-policy/',
withPersonalizedAds: false,
withNonPersonalizedAds: true,
withAdFree: false,
});
console.log('formResult', formResult);
}
} catch (e) {
console.log('error', e.message);
}
}
Related
I am creating a React Native app for Android using Expo, EAS Build.
Following the docs here, I set up notifications for my app, including Firebase Cloud Messaging.
In my code, which is mostly taken from the docs, I check for notifications permission upon app launch using UseEffect, and if the app does not have permission, I request the permissions.
However, when I load the app on my development server, the alert pops up stating, "Failed to get push token for push notification!"
Just to make sure everything else is working, I went and enabled notification permission manually on my device via settings. Then, the app works great. The notifications I am scheduling work. There are no problems.
But obviously, I don't want the user to have to manually go to settings. I'd like the prompt to appear.
Could this be an issue with the development server which will no longer exist once deployed?
Any help appreciated. Thanks.
Here is what I believe to be the relevant code below from my App.js. I expected a prompt to appear for the user when they open the app the first time asking them to give notification permission.
import * as Notifications from "expo-notifications";
// other import statements
Notifications.setNotificationHandler({
handleNotification: async () => {
return {
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
};
},
});
// other code
export default function App() {
// other code
const notificationListener = useRef();
const responseListener = useRef();
useEffect(() => {
registerForPushNotificationsAsync().then(token => setExpoPushToken(token));
// This listener is fired whenever a notification is received while the app is foregrounded
notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
});
// This listener is fired whenever a user taps on or interacts with a notification (works when app is foregrounded, backgrounded, or killed)
responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
// console.log(response);
});
return () => {
Notifications.removeNotificationSubscription(notificationListener.current);
Notifications.removeNotificationSubscription(responseListener.current);
};
// other unrelated code
}, []);
// code related to the app itself
}
// below is the function i call above upon app launch in order to get notification
// but no prompt comes up for the user
async function registerForPushNotificationsAsync() {
let token;
if (Device.isDevice) {
console.log('about to getPermissionsAsync');
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
console.log('about to requestPermissionsAsync');
const { status } = await Notifications.requestPermissionsAsync();
console.log('the status gotten by requestPermissionsAsync() is the line below this: ');
console.log(status);
finalStatus = status;
}
if (finalStatus !== 'granted') {
alert('Failed to get push token for push notification!');
return;
}
console.log('about to get token');
token = (await Notifications.getExpoPushTokenAsync({
experienceId: '#johnquiet/buglecallexplore ',
})).data;
console.log('should see token below this line');
console.log(token);
} else {
alert('Must use physical device for Push Notifications');
}
if (Platform.OS === 'android') {
Notifications.setNotificationChannelAsync('alarms', {
name: 'Scheduled Notifications',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#a7e7fa',
});
}
return token;
}
// more unrelated code and styles
On Android 13 the prompt asking to grant the permission will not appear until at least one notification channel is created. Make sure to call Notifications.setNotificationChannelAsync before calling Notifications.getExpoPushTokenAsync.
https://docs.expo.dev/versions/latest/sdk/notifications/#permissions
I am trying to do the following:
User asks to reset his password
Email is sent with a CODE and an URL to visit to reset his password
User visits the URL inputs the code and the new password and I call the confirmPasswordReset
But this doesn't work, the docs, their examples and also their functionality differs. Here's what happens
Greeting,
Follow this link to reset the example#gmail.com account password for the Example Dev app.
the URL
No Code, nothing, if I follow the URL it will take me to Firebase hosted app that will handle the reset with an ugly looking UI and THEN redirect me to the specified URL in the settings for sendResetEmail...
While the docs specify expected behavior, it differs from the actual one.
Sends a password reset email to the given email address.
#remarks
To complete the password reset, call confirmPasswordReset with the code supplied in the email sent to the user, along with the new password specified by the user.
#example
const actionCodeSettings = {
url: 'https://www.example.com/?email=user#example.com',
iOS: {
bundleId: 'com.example.ios'
},
android: {
packageName: 'com.example.android',
installApp: true,
minimumVersion: '12'
},
handleCodeInApp: true
};
await sendPasswordResetEmail(auth, 'user#example.com', actionCodeSettings);
// Obtain code from user.
await confirmPasswordReset('user#example.com', code);
The docs specify my intended behavior, but when used, it's totally different. What is happening here?
const onSubmit = (data: PasswordResetData) => {
setIsLoading(true);
sendPasswordResetEmail(getAuth(), data.email, {
url: "http://localhost:3002/en/auth/reset/confirm?email=" + data.email,
handleCodeInApp: true,
})
.then(() => {
})
.catch((err) => {
console.error(err);
})
.finally(() => {
setIsLoading(false);
});
};
I have given a task to code about sending email verification to user after they have registered themselves in signup screen which is react native based. Create new user is handle in one js file called AuthProvider.js. In one of the return value of AuthContext.Provider, there is one action which handle create new user which is shown code below and is working fine.
registerWithEmail: async (userDetails) => {
const { email, password } = userDetails;
return await auth()
.createUserWithEmailAndPassword(email, password)
.then(() => {
//wish to add on the send email verification action here
return true;
});
}
The return true code above is used to do checking in signup screen. If I wish to return the true value only if the condition where verification email is send to them and is clicked. How can I do it and can I have any kind of guidance?
You can use async-await syntax with `try-catch this way.
registerWithEmail: async (userDetails) => {
try {
const { email, password } = userDetails;
const {user} = await auth().createUserWithEmailAndPassword(email, password)
await user.sendEmailVerification()
return true
} catch (e) {
console.log(e)
return false
}
It'll return true only when the email is sent. If there's any error in the function it'll trigger catch and the function will return false.
I don't know more about react-native but in android studio when we send verification email and when user clicked on it. We have firebase function to check user clicked on verification link or not.
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user.isEmailVerified())
{
// user is verified, so you can finish this screen or send user to other screen which you want.
}
i hope it will help you and give you some idea...
I have a web app that needs to acces to camera, but I want to ask camera permission manually, because if the web app detects automatically camera permission, it will do it "too late".
What I need is to ask for permission, then I could render a 3rd party javascript function that renders a camera.
With react native is easy, but with normal React I can't find a way to ask when I want those permissions, for Chrome and Safari.
Any idea?
Prior to the link on the comment of #Shubh (thanks) I get it working only for Chrome:
navigator.permissions.query({ name: 'camera' })
.then((permissionObj) => {
console.log(permissionObj.state);
permission = permissionObj.state;
})
.catch((error) => {
console.log('Got error :', error);
});
But this is not supported for iphone IOS (Safari).
Now with getUserMedia() API I have this code semi-working:
let stream = null;
const constraints = {
video: true
};
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
/* use the stream */
} catch (err) {
/* handle the error */
}
My only problem here is the light on the camera (desktop) get stucked, I'm trying to find now how to "close" the getUserMedia, I just want to grant permissions, like the first way.
Edit: now for turn off the camera I did this:
const askCameraPermission =
async (): Promise<MediaStream | null> => await navigator.mediaDevices.getUserMedia({ video: true });
let localstream: MediaStream | null;
askCameraPermission()
.then(response => {
localstream = response;
})
.then(() => {
localstream?.getTracks().forEach(track => {
track.stop();
});
})
.catch(error => console.log(error));
navigator.getUserMedia({audio:true,video:true}, function(stream) {
stream.getTracks().forEach(x=>x.stop());
}, err=>console.log(err));
Take the stream, get the tracks and stop them to turn off the camera. Camera will still flash, but it will turn off.
Here is the demo: https://codesandbox.io/s/camera-app-86me8?file=/src/App.js
Make sure you check the error in the catch... it told me my problem...didn't have an input device connected!
I have successfully created an API that uses passport-google-oauth to return a JWT. Currently when I go through the process using my API routes it returns a json object with a JWT Bearer token.
I am attempting to use Reactjs on the front end however am running into a couple issues.
In my signin button component I am just trying to retrieve the result with the bearer token to pass it into a reducer
When using Axios -> I am running into a CORS issue when using exios and cant return a result, when adding CORS into my build and a proxy to my react project I recieve the following error No 'Access-Control-Allow-Origin' header is present on the requested resource.
When I use a anchor tag with href link the authentication successfully works however it redirects to the /api/auth/google/callback link itself instead of allowing me to catch the bearer token and then run it through my reducers to save it into local storage and update my state.
Am I missing a step? Ive looked for a few hours at various resources online and cant seem to find the solution im looking for
React
(for simplicity at the moment I am just trying to catch the response, which should be returned bearer token, however I am unable to do this)
googleAuth = (e) => {
e.preventDefault()
axios.get('/api/auth/google')
.then(res => console.log(res))
.catch(err => console.log(err))
}
render() {
return (
<button onClick={this.googleAuth}>Signin With Google</button>
)
}
API
Routes
router.get('/google', passport.authenticate('google', {
session: false,
scope: ['profile', 'email']
}))
router.get('/google/callback', passport.authenticate('google', { session: false }), generateUserToken)
Strategy
passport.use(new passportGoogle.OAuth2Strategy(googleConfig, async (request, accessToken, refreshToken, profile, done) => {
// Check for existing user
const existingUser = await User.findOne({
providers: {
$elemMatch: {
provider: 'Google',
providerId: profile.id
}
}
})
// If user exists return done
if (existingUser) return done(null, existingUser)
// If user does not exist create a new user
const newUser = await new User({
name: profile.displayName,
providers: [
{
provider: 'Google',
providerId: profile.id
}
]
}).save()
// Create profile with new user information
const newProfile = await new Profile({
userId: newUser.id
}).save()
return done(null, newUser)
}))
I've looked a bit at your code and haven't seen any serializing/deserializing going on. Usually you'd have to go through this process to be able to connect with whatever authentication strategy you are using.
Here is a snippet of code that you could use in the file you keep your strategies:
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id).then(user => {
done(null, user);
});
});
Maybe you could look it up in more detail in the documentation. Here is a link http://www.passportjs.org/docs/ go to the sessions part. Plus, make sure to look at how the app.use is put together with the .session() func.