Question: How to make use of `redirectUrl` inside `signInSuccessWithAuthResult`
gr-qft opened this issue · 14 comments
Hello,
I'm using email link authentication for my app. In the app, there're two kinds of users, normal users and admin users, and I would like to be able to redirect them differently after a sign-in success. How would I do that? I've checked around but still have no idea. I'm thinking redirectUrl
inside signInSuccessWithAuthResult
might have something to do with this but I'm not sure. I'll really appreciate any help.
Just a note. I think as the last resort it's always possible to have the same redirect for both users, but render the views differently. But I would really appreciate any help or comment.
Thanks!
I assume you are using custom claims to differentiate between normal and admin users.
If so, you can add a signInSuccessWithAuthResult
callback and check the user's custom claims there:
signInSuccessWithAuthResult:(authResult, redirectUrl) => {
authResult.user.getIdTokenResult().then(tokenResult => {
if (tokenResult.claims.admin) {
window.location.assign('/admin');
} else {
window.location.assign('/user');
}
});
}
@bojeil-google Thanks for the answer. So, we have to use window.location
directly, and the parameter redirectUrl
is not usable? I'm asking this because signInSuccessUrl
, if given a value, will work (if at the end of signInSuccessWithAuthResult
I return true
).
I've really tried to read the firebase doc and somewhere it mentions passing a url, using emailLinkSignIn
. But it seems to me for handling email link sign-in firebase sets the mode as signIn automatically as well as a default continueUrl and it's not possible to overwrite those, is that true?
Thank you!
I assumed that you had a more complicated logic where you check the user claim and redirect based on that.
I haven't tested it in a while but I believe you can also pass the signInSuccessUrl
query parameter in the URL and the value of that will be either passed back in the callback or will be redirected to on success.
You can also just set the signInSuccessUrl
in the config without setting a callback.
These 2 options assume you know the type of user ahead of time. If you don't know the type of user until sign in is successful, you are better off using the callback approach.
BTW, returning true
in signInSuccessWithAuthResult
callback will continue the redirect to the expected URL (signInSuccessUrl
or redirectUrl
) had the callback not been provided.
When using emailLinkSignIn
, the url
is the object returned is mainly the URL to redirect to when the user clicks the sign in link in their email inbox. You can pass a custom URL there too and then retrieve it in the success callback by checking the current URL via window.location.href
. I think you have a variety of options here.
Thanks for the info. I've really tried the option emailLinkSignIn
but the sign-in link in the email is always the same (as I wrote, mode and continueUrl seem to be set by firebase and I couldn't do anything to change them). It would be really nice if emailLinkSignIn
works as documented. What do you recommend?
I believe the continueUrl
is affected by the url
value returned in the emailLinkSignIn
callback. We use this object when triggering sign in with email link.
I've tried repeatedly many times but it's not working, mode
and continueUrl
in the sign-in link are always the same regardless of what I do.
Can you provide snippets of your configuration to make sure we are on the same page? The code should use the current URL as the default url
but will overwrite it with the one you return in the emailLinkSignIn
callback. The mode will always be the same for email link sign in.
Ok here's what I have. I've tried different settings (like returning false
inside signInSuccessWithAuthResult
and setting handleCodeInApp
to false
etc. Like I said, I've checked the email sign-in link repeatedly and it's always the same no matter what I do. (https://xxx.firebaseapp.com/__/auth/action?apiKey=xxx&mode=signIn&oobCode=xxx&continueUrl=http://192.168.2.14:3399/login?xxxlang=en). Also, lang=en
is set automatically and I don't know how to change that also.
const firebaseAuthConfig = {
signInFlow: "redirect",
signInOptions: [
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD
}
],
signInSuccessUrl: "http://192.168.2.14:3399/me",
credentialHelper: "none",
callbacks: {
signInSuccessWithAuthResult: async (authResult, redirectUrl) => {
const { user } = authResult;
const userData = await mapUserData(user);
setUserCookie(userData);
return true;
}
},
emailLinkSignIn: () => {
return {
url: "http://192.168.2.14:3399/me?showPromo=1234",
handleCodeInApp: true
};
}
};;
Please note that http://192.168.2.14:3399/login
is where the I require the sign-in email.
This works as expected. The url http://192.168.2.14:3399/login
is set as the continue URL. We always redirect to the action url which redirects back to the continueUrl
. If you want to change that, you need to do from the Firebase Console email template section.
As for the language, check these sections:
- https://github.com/firebase/firebaseui-web#localized-widget
- https://github.com/firebase/firebaseui-web#building-firebaseui
You need to localize the UI itself and the email link. When you localize the UI, it will propagate the language to the email template.
I'm not following: I set url
inside emailLinkSignIn
to /me
but continueUrl
in the link email sent is always /login
. The address http://192.168.2.14:3399/login
is not explicitly set by me anywhere (I set /me
instead). In fact, right now, the only way I get the right redirect is to use signInSuccessUrl
, but this is not dynamic. So what I've been seeing is whatever I write inside emailLinkSignIn
are ignored.
Thanks for the links about the languages!
Hmm, you are right. I missed the /me
path. I will need to test to see why it is not honoring your url
. Can you try using just the path /me?showPromo=1234
?
I just tried, continueUrl
in the link is still /login
. Moreover, it seems if I have signInSuccessUrl
then eventually I'll be redirected to it whether or not I return true
or false
inside signInSuccessWithAuthResult
.
By the way, it seems because of the above at present there's no way to redirect from inside signInSuccessWithAuthResult
.
Thanks!
Hey @gr-qft I tested this on my end with various url
returned in the emailLinkSignIn
callback:
- Relative link with just a different path
- Absolute link with same domain and different path.
- Link with different domain and path.
- Link with IP address and path
- Link with IP address, port number and path
- Link with IP address, port number, path and query string
I cannot recreate your issue. All of the above are appended in the continueUrl
as expected.
To be honest, I have no idea why it is not working for you.
Hey @bojeil-google ,
Thanks for testing! I've tried again and it's still not working, in every case the continueUrl in the link is always /login
.
If it helps, the template I see on console is https://xxx.firebaseapp.com/__/auth/action?mode=action&oobCode=code
, and mode and continueUrl are set automatically for me!! Also, this is how I use setting:
const FirebaseAuth = () => {
return (
<div>
<StyledFirebaseAuth
uiConfig={firebaseAuthConfig}
firebaseAuth={firebase.auth()}
/>
</div>
);
};
This is a very weird problem. If it's ok with you, I can give you access to my code. It's mostly based on this:
https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication