Firebase popup signin popup-closed-by-user error - javascript

I am trying to use the Javascript client library for Firebase auth to sign in with a Google account and popup window. However, when I try to sign in, the signin window pops up, I select my Google account, and then it spends about 10 seconds loading (with the blue progress bar moving), then the popup window closes, and shortly after I get the following error message:
code: "auth/popup-closed-by-user"
message: "The popup has been closed by the user before finalizing the operation."
I have enabled Google signin in the authentication section of the Firebase web UI. Below is the code I am using which is pretty much directly copied from the Firebase docs. I have made no other changes to the project config. I started a new project just to test this and have simply run firebase init, enabling only hosting, and enabling Google signin in the authentication web UI.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Welcome to Firebase Hosting</title>
<script src="/__/firebase/7.14.6/firebase-app.js"></script>
<script src="/__/firebase/7.14.6/firebase-auth.js"></script>
<script src="/__/firebase/init.js"></script>
</head>
<body>
<button id="signin">sign in</button>
<button id="signout">sign out</button>
<script>
const provider = new firebase.auth.GoogleAuthProvider();
const signinButton = document.querySelector("#signin");
signinButton.addEventListener("click", () =>
firebase
.auth()
.signInWithPopup(provider)
.then(function (result) {
console.log("result", result);
})
.catch(function (error) {
console.error(error);
})
);
const signoutButton = document.querySelector("#signout");
signoutButton.addEventListener("click", () =>
firebase
.auth()
.signOut()
.then(function () {
console.log("signed out");
})
.catch(function (error) {
console.error(error);
})
);
</script>
</body>
</html>

See this issue: https://github.com/firebase/firebase-js-sdk/issues/3188.
For some users, this is resolved by adding the app domain to the list of authorized domains:
Firebase Console -> Auth -> Sign-In Method -> Authorized Domains -> Add (domain)

For some users this may be caused by the Firefox Containers feature, or by the Firefox Enhanced Tracking Protection feature, specifically its isolate other cross-site cookies feature.

Related

next js api route or call firestore directly from client side

Hi i'm new to next js and had a few questions regarding using firebase authentication client side and server side. I have both firebase admin and firebase client sdks setup in my project. I have a signup page user routes to. They fill in name email and password.
I'm using client side to authenticate with email and password createUserWithEmailAndPassword when the user submits the form on the signup page.
Questions:
[1]
I want to save the auth response of user name and uid to firestore db when user is created. Should I do this in the same submit handler as the auth response happens ?
const onSignup = async ({ email, password }: Tfields) => {
try {
const response = await auth.signup(email, password);
/ *** DO I save to firestore DB here ? **/
// route to authenticated page
router.push("/account");
} catch (error) {
});
}
};
[2]
If calling firestore from handler above should I be calling firestore directly using the firebase client side sdk or should I create an api route in nextjs called createDBUser and call the api from handler. Wouldn't this be safer connecting to firestore using api instead of directly with client side sdk ?
[3]
Example authorized route like /account this is essentially a SSG at build time.
Wont this show nothing on the page at first which is not very SEO friendly. Only the header SEO component will be viewable at first until the firebase client side check happens ?
const Account = () => {
const [user, setUser] = useState<any>(null);
const handleUser = (user) => {
setuser(user)
}
useEffect(() => {
const unsubscribe = onIdTokenChanged(getAuth(), handleUser);
return () => unsubscribe();
}, []);
return (
<div>
<Head>
<title>Authorized User page</title>
<meta
name="description"
content="this is john doe's page with all his account pages"
/>
</Head>
{user && <div>
<div>This is a authenticated account page</div>
</div> }
</div>
);
};
export default Account;
Or Should I be using getServerSideProps in the account page instead to check if user is logged in instead of doing this in the useEffect. Wouldn't this have all the content rendered on the server before its served to the user ? Also I would be able to inject users name inside the seo header as it will be rendered on server before hand.
Interacting with Firestore directly or via a server depends on your case and opinions may vary. But is it worth adding another API route, verifying user tokens and then adding data to Firestore when that can be directly and secured using security rules? Yes, you can add data to Firestore right after createUserWithEmailAndPassword() creates a user.
Routing Firestore requests via your API would be useful if you need any sort of rate limit on updating documents or any operations.
For server side rendered web apps, I would recommend using sessions cookies so you can authenticate user before render. Here you would have to verify the cookie using Admin SDK and and fetch data to show before page renders.

Recaptcha call back can be found when it is the only function but not when other ones are included

I am trying to make a discord bot verification page where users verify that they are not a robot. I have run into an error where Recaptcha cannot find my recaptchaCallBack function. It recognizes it when it is the only function and doesn't when other functions are included.
Here is the code:
import { initializeApp } from "https://www.gstatic.com/firebasejs/9.6.4/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/9.6.4/firebase-analytics.js";
import { getDatabase } from "firebase/database";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
//config
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
const db = getDatabase();
function recaptchaCallback() {
set(ref(db, "verified/" + userVarFormatted), {
name: userVarSplitted[0],
discriminator: userVarSplitted[1]
});
}
<html>
<head>
<title>Jerry Bot Verication</title>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="?" method="post" data-callback="XXX" class="recaptchaDIV">
<div class="g-recaptcha" data-callback="recaptchaCallback" data-sitekey="my site key"></div>
</form>
<!--My js code was here-->
</body>
</html>
Do you know what is causing this?
Thanks
If you're talking about just a regular web page, there's no mechanism for require("mongodb") to work. (You'd need a bundler.)
Even if it did, a browser can't directly talk the MongoDB protocol.
Even if it could, you'd now expose your MongoDB credentials to anyone who would visit the page, so they could read and tamper with your database however they'd like, which is likely not what you want.

Firebase - check if user created with Google Account is signing up or logging in?

I'm trying to create a web application, where you can log-in and register an account with a google account. I have managed to make it so they can log-in with the signInWithPopup(provider), but not sure how to Implement the sign-up. Any suggestions? or know of any functions in firebase i can use?
There aren't any separate methods to login and sign up when using Google Sign-In or any other provider. If a user with that credential exists then user will be logged in else a new user account will be created. You can then use additionalUserInfo.isNewUser property from the result received from signInWithPopUp method to check if the user is new.
firebase.auth().signInWithPopup(provider).then(function (result) {
const {additionalUserInfo: {isNewUser}} = result;
console.log(isNewUser ? "This user just registered" : "Existing User")
})
For the new Modular SDK (V9.0.0+), the same can be written as:
import { signInWithPopup, getAdditionalUserInfo } from "firebase/auth"
const result = await signInWithPopup(auth, googleProvider);
// Pass the UserCredential
const { isNewUser } = getAdditionalUserInfo(result)
So far, as I understood, you have two options to log in to your website: one is to make a local username/password account on your website, and the other option is to use your google account. I suppose the best way would be to check if the Google account is linked to any existing user using additionalUserInfo.isNewUser, and then linking up your google account with the account that is created via your website locally by following this article: https://firebase.google.com/docs/auth/web/account-linking?hl=lt
Once you have Firebase dependency inside your application. You can use createUserWithEmailAndPassword method to do that.
firebase
.auth()
.createUserWithEmailAndPassword("email#domain.com", "123123")
.then(data => {
data.user.updateProfile({
displayName: this.form.name
}).then(() => {});
})
.catch(err => {
this.error = err.message;
});

Paypal subscription confusion

I've been working on a project for over 2 years and I am finally ready to launch, but first I have to integrate a subscription based payment option so I can actually make some money off of this thing. I've been trying to integrate paypal subscriptions for like 2 months now and it's a major hold up. Also, this is causing me to go bald. Please help!
I think it would be really helpful to have a kind of overview explanation describing the definate process that I need to follow in order to accept subscription based payments. The level of detail would include where each of the steps should occure; frontend or backend (server), and any intermediate steps necessary to understand what data is flowing where. Second to that, the actual code for the smart button with some comments indicating what part of the process the code is addressing. Maybe that's a lot to ask, but it would be greatly appreciated and I believe a great resource for others looking to do the same as I am currently.
At the moment, my primary issue is that when I set the URL pointing to the paypal SDK in my script take to include &intent=authorize, I am told in the error message that I need to set intent=capture, but when I set intent=capture I'm told I need to set intent=authorize. So now I'm confused as to what I am supposed to do; authorize the transaction or capture the transaction. I've been provided links to 2 different guides on the paypal developer website from paypal technical support which seem to contradict each other - the first link said nothing about capture or authorizing payments, the 2nd link does. But I don't understand the context on the second link. The first link is all client side, the second link is on client side and server side. Why would these intent=ca[ture/authorize be needed? I thought that once someone agrees to and completes signing up for a subscription, and I've captured their subscription id, that I don't need to do anything else in order to receive funds on the monthly basis setup in my plan, I would only have to query the paypal APIs to find out if they've paid up upon the customer signing in to my service.
I have setup a sandbox account and I've created a product and a plan. I've got the smart button rendering with my plan ID after the customer logs in.
If I set intent=capture in the paypal SDK script URL, the paypal window opens, you select payment and agree, and then I get this error in my console:
env: "sandbox"
err: "Error: Use intent=authorize to use client-side authorize"
referer: "localhost:88"
timestamp: "1589939180937"
uid: "fad5852fa3_mde6ndq6mdu"
But if I set intent=authorize, I click the smart button, the paypal window shows up and disappears quickly and then I get this error:
buttonSessionID: "e3bf3c6c3d_mdi6mdi6mzq"
env: "sandbox"
err: "Uncaught Error: Expected intent from order api call to be authorize, got capture. Please ensure you are passing intent=capture to the sdk url"
referer: "www.sandbox.paypal.com"
sessionID: "fad5852fa3_mde6ndq6mdu"
timestamp: "1589940160835"
Here is my code:
<!DOCTYPE html>
<head>
<!-- Add meta tags for mobile and IE -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
</head>
<body>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<script
src="https://www.paypal.com/sdk/js?client-id=CLIENT-ID-HERE&currency=USD&vault=true&intent=capture"></script>
<script>
let planid = 'P-48A5110983270751ML2P5NVI';
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
// Set up the transaction
createSubscription: function (data, actions) {
// Create Subscription
return actions.subscription.create({ "plan_id": planid });
},
onApprove: function (data, actions) {
// Authorize the transaction
actions.order.authorize().then(function (authorization) {
// Get the authorization id
var authorizationID = authorization.purchase_units[0]
.payments.authorizations[0].id
// Call your server to validate and capture the transaction
return fetch('/api/company/paypal-transaction-complete', {
method: 'post',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
orderID: data.orderID,
authorizationID: authorizationID,
data: data,
authorization: authorization
})
});
});
}
// Finalize the transaction? Which one do I want, to authorize or to finalize??
// onApprove: function (data, actions) {
// let result = actions.subscription.get();
// return actions.order.capture().then(function(details) {
// // Do I need to send something to my server here?
// // Show a success message to the buyer
// alert('Transaction completed by ' + details.payer.name.given_name + '!');
// });
// }
}).render('#paypal-button-container');
</script>
</body>
Thanks in advance for your help. This has been a most frustrating project.
Why are you using intent=authorize / intent=capture in the URL with subscriptions?
Why are you using actions.order.authorize() with subscriptions?
Who told you to do either of these things with subscriptions?
Please see the Subscriptions Integration guide, which does not include any mention of those things.

Firebase createUserWithEmailAndPassword not working

I'm just trying to get simple email/password authentication working. As a test, trying to just create users. It's not working, when clicking the button to pass some hard-coded email/password vars to auth, I get this console error below. As far as I understand I should be able to do this from client-side without having to set up any server. I also have firebase email/password authentication enabled in firebase console.
{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "accessNotConfigured",
"message": "Access Not Configured. Google Identity Toolkit API has not been used in project 87795057294 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/identitytoolkit.googleapis.com/overview?project=87795057294 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.",
"extendedHelp": "https://console.developers.google.com/apis/api/identitytoolkit.googleapis.com/overview?project=87795057294"
}
],
"code": 403,
"message": "Access Not Configured. Google Identity Toolkit API has not been used in project 87795057294 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/identitytoolkit.googleapis.com/overview?project=87795057294 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry."
}
}
Though I did check and Google Identity Toolkit API is enabled
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="UTF-8">
<title>Firebase Auth Test</title>
<!-- Firebase JavaScript Link -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.12.1/firebase-database.js"></script>
</head>
<body>
<!-- JQuery -->
<!-- ================================================================================== -->
<script>
$(document).ready(function() {
// Initialize Firebase
// This is the code we copied and pasted from our app page
var config = {
apiKey: "AIzaSyBJOZIBC9J3MUfkLfXGKgvaNYxilplQ7fI",
authDomain: "project1-e7460.firebaseapp.com",
databaseURL: "https://project1-e7460.firebaseio.com",
projectId: "project1-e7460",
storageBucket: "project1-e7460.appspot.com",
messagingSenderId: "87795057294"
};
firebase.initializeApp(config);
var email = "geochanto#yahoo.com";
var password = "Abc1234!";
// Get a reference to the database service
var database = firebase.database();
var clickCounter = 0;
$("#clickme").on("click", function() {
console.log('clicked!');
clickCounter++;
database.ref().set({
clickCount: clickCounter,
em: email,
pa: password
});
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
});
});
</script>
<button id="clickme">Click Me</button>
</body>
</html>
You need to login to your Firebase Console and enable the Sign-In Method.
See the point 3 of the Before You Begin section in the Authentication documentation.
Enable Email/Password sign-in:
In the Firebase console, open the Auth section.
On the Sign in method tab, enable the Email/password sign-in method and click Save.
Then try again - it should work once enabled.

Categories

Resources