Credential from Firebase EmailAuthProvider not working - javascript

I use firebase with react then need to convert anonymous account to permanent. I have follow firebase doc but when I try look like cannot use this function they have error message as undefined
in code
let credential = firebase.auth.EmailAuthProvider.credential(email, pass)
error message
Uncaught TypeError: Cannot read property 'credential' of undefined
Someone please help me to fix a problem
ps. in my package
"firebase": "^4.5.0"

First check whether you are anonymously signed in or not.Below code will be helful to do so.
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
// User is signed in.
var isAnonymous = user.isAnonymous;
var uid = user.uid;
// ...
} else {
// User is signed out.
// ...
}
// ...
});
If you get some defined values then use EmailAuthProvider to get credentials.
var credential = firebase.auth.EmailAuthProvider.credential(email, password);

Related

Firebase save function error when updating database

I am trying to update my price, and I keep getting this error upon clicking the Save button. This is the error code I'm getting:
Uncaught ReferenceError: user is not defined
at updatePrice (settings.js:52:43)
at HTMLButtonElement.onclick (VM148 settings.html:284:132)
I have provided my JavaScript code below. This is how I'm calling my function in HTML as well:
<button class="priceSave" type="submit" id="save11" value="save11" onclick="updatePrice()">Save</button>
JavaScript code updated:
// Initialize Firebase
firebase.initializeApp(firebaseConfig);
// Initialize variables
const database = firebase.database();
const auth = firebase.auth();
firebase.auth().onAuthStateChanged((user) => {console.log(user);});
function updatePrice() {
// Get data
numberInput = document.getElementById("numberInput").value;
const user = firebase.auth().currentUser;
// Enter database location
firebase
.database()
.ref(user.uid + "/prices/roomA/serviceOne")
.update({
//studioName : studioName,
numberInput: numberInput,
});
}
As a matter of fact, user is not defined in the updatePrice() function. In your code, it's only within the callback function passed to the onAuthStateChanged() observer that user is defined.
You need to use the currentUser property as follows:
function updatePrice() {
//Get data
numberInput = document.getElementById("numberInput").value;
const user = firebase.auth().currentUser;
//Enter database location
firebase
.database()
.ref("/studiopick/studio/users" + user.uid + "/prices/roomA/serviceOne")
.update({
//studioName : studioName,
numberInput: numberInput,
});
}
However, you need to take into account that currentUser could be null. This can happen if the auth object has not finished initializing (more information by reading the entire following documentation section).
So, for example, before calling this function, check that firebase.auth() is not null. If it is the case, you can retry in some few seconds or indicate the user to try later.

Firebase user.linkWithCredential is not a function

I've followed this tutorial on how to link existing credentials with the new credentials from Facebook and everything is working as expected, except for the last part which is linking the user with the new credentials, I keep getting "user.linkWithCredential is not a function" error.
Here's my code:
$(document).on('click', "#btn-login-fb", function (event) {
//A bunch of code here where I do the login process
}).catch(function (error) {
//Here is where I need to handle the error and link accounts
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;
//
// LINKING FACEBOOK WITH EXISTING EMAIL/PASSWORD USER
//
if (error.code === 'auth/account-exists-with-different-credential') {
// Step 2.
// User's email already exists.
// The pending Facebook credential.
var pendingCred = error.credential;
// The provider account's email address.
var email = error.email;
// Get sign-in methods for this email.
firebase.auth().fetchSignInMethodsForEmail(email).then(function (methods) {
// Step 3.
// If the user has several sign-in methods,
// the first method in the list will be the "recommended" method to use.
if (methods[0] === 'password') {
// Asks the user their password.
// In real scenario, you should handle this asynchronously.
//Abrir modal
document.getElementById("btnPwModal").click();
$(document).on('click', "#btnConfirmPw", function (event) {
document.getElementById("btnFecharModal").click();
var password = $("#inputPassword").val();
firebase.auth().signInWithEmailAndPassword(email, password).then(function (user) {
// Step 4a.
user.linkWithCredential(pendingCred).then(function () {
alert("linko");
// Facebook account successfully linked to the existing Firebase user.
});;
});
})
}
});
}
});
});
Any ideas on why everything else is working but linkWithCredential is not? Thanks.
What you get after calling signInWithEmailAndPassword is a UserCredential object, not a User object. To get from UserCredential to ``, you call user on it.
So:
firebase.auth().signInWithEmailAndPassword(email, password).then(function (cred) {
cred.user.linkWithCredential(pendingCred)...

Trying to use fetchSignInMethodForEmail

I am trying to discover how to make a statement appear when someone registering to the form that I was made but the email address was already used. I am using firebase. I am not familiar with fetchSignInForEmail and am wondering how to use it and implement it.
I am thinking I can use an if statement
if(email exists) {
push firebase user to directed page
} else {
statement.style.display === block
}
I am also curious on how to do this with passwords as well.
Thank you
Listen for that error. However, I prefer to merge the accounts and let the user sign in. Below is an example snippet. I've got this done for you, provided you want to allow email link authentication (no password required). Firebase offers a pre-rolled one as well that supports passwords and federation/oAuth (twitter, facebook, etc).
} catch (error) {
if(error.code === "auth/email-already-in-use"){
// REMEMBER AUTH CURRENT USER OBJECT
previousUser = firebase.auth().currentUser;
// WE MUST HANDLE DB READ AND DELETE WHILE SIGNED IN AS PREVIOUS USER PER FIRESTORE SECURITY RULES
if(localUserDoc){
if(localUserDoc.data().apples){
apples = localUserDoc.data().apples;
}
}
//DELETE CURRENT USER RECORD WHILE STILL SIGNED IN
await firebase.firestore().collection("users").doc(previousUser.uid).delete();
// CLEAN UP DONE. NOW SIGN IN USING EMAIL LINK CREDENTIAL
try {
var firebaseUserObj = await firebase.auth().signInAndRetrieveDataWithCredential(credential);
// FIRESTORE USER RECORD FOR EMAIL LINK USER WAS CREATED WHEN THEY ADDED APPLE TO CART
try {
var doc = await firebase.firestore().collection("users").doc(firebaseUserObj.user.uid).get();
if (doc.exists) {
if(doc.data().apples){
apples = apples + doc.data().apples;
}
}
await firebase.firestore().collection("users").doc(firebaseUserObj.user.uid).update({
apples: apples
});
} catch(error) {
console.log("Error getting document:", error);
}
previousUser.delete();
} catch (error) {
console.log(".signInWithCredential err ", error);
}
}
}

How to determine if the user signed in to Firebase with email and password or with google sign in?

I am working on a log in for a web application, and I have made it so the user can sign in manually with their email and password or by using a google sign in. Is there a way to determine which method they used? Preferably by using the Firebase authentication state change function.
`firebase.auth().onAuthStateChanged(firebaseUser => {....`
I know you can tell how they signed in when you go into the Firebase console log but is there a way to determine it using JavaScript code?
When using firebase.auth().currentUser.providerData the following:
#mjrdnk's answer is correct, but there is a caveat, a user could have multiple providers linked. So using firebase.auth().currentUser.providerData[0].providerId will always yield the same provider even when another linked provider was used to sign in. The most accurate way to determine the current provider used to sign is by inspecting the ID token's field: firebase.sign_in_provider.
You can determine by using currentUser https://firebase.google.com/docs/reference/js/firebase.UserInfo
Like this:
firebase.auth().currentUser.providerData[0].providerId
Hope this helps.
Currently #mjdnk asnwer depracated, because it will gives always first provider not the last logged in.
So most recent solution is:
As noted here
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function(authResult, redirectUrl) {
var providerId = authResult.additionalUserInfo.providerId;
localStorage.setItem("firebaseProviderId", providerId)
//...
},
//..
}
and for display in page
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
user.getIdToken().then(function (idToken) {
$('#user').text(welcomeName + "(" + localStorage.getItem("firebaseProviderId")+ ")");
$('#logged-in').show();
}
}
});
#mjrdnk's answer is correct, but there are cases that are not covered by the answer so I find that this solution works best in all cases (that I have tested).
val user = firebaseAuth.currentUser
user?.let {
authProvider = when (it.providerData[it.providerData.size-1].providerId) {
"phone" -> {
ConnectedUser.LOGIN_PROVIDERS.PHONE
}
"password" -> {
// Email and password
ConnectedUser.LOGIN_PROVIDERS.EMAIL
}
else -> {
ConnectedUser.LOGIN_PROVIDERS.UNKNOWN
}
}
.
.
.
Wonderful source of information: FirebaseUI for Auth
Some provider names follow (see above source code for more):
ANONYMOUS_PROVIDER = "anonymous"
EMAIL_LINK_SIGN_IN_METHOD = "emailLink"
EMAIL_PASSWORD_SIGN_IN_METHOD = "password"
MICROSOFT_PROVIDER = "microsoft.com"
YAHOO_PROVIDER = "yahoo.com"
APPLE_PROVIDER = "apple.com"
PHONE = "phone"

How to use Google Dart with Firebase Simple login (pass function inside function)

Has anybody figured out how to use the Firebase Simple Login with Google Dart? I am trying to figure out how to define function(error, user){} when calling FirebaseSimpleLogin. Both error and user() are objects.
This is the sample javascript code from Firebase
var myDataRef = new js.Proxy(js.context.Firebase, 'https://johnstest1.firebaseIO.com/');
var myDataRef = new Firebase('https://johnstest1.firebaseIO.com/');
var auth = new FirebaseSimpleLogin(myDataRef, function(error, user) {
if (error) {
// an error occurred while attempting login
console.log(error);
} else if (user) {
// user authenticated with Firebase
console.log('User ID: ' + user.id + ', Provider: ' + user.provider);
} else {
// user is logged out
}
});
This is the code added to the html file for use by both Dart and Firebase
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase-simple-login.js'></script>
<script type="application/dart" src="firebasetestlogin.dart"></script>
<script src="packages/browser/dart.js"></script>
<script src="packages/browser/interop.js"></script>
In the .dart file the javascript library has been imported using pubspec.yaml
import 'package:js/js.dart' as js;
In the main() this line of code works fine and I am able to write data to the database. The line that is commented out is the original javascript line while the next line is the Dart version and it works.
js.scoped((){
// var myDataRef = new Firebase('https://johnstest1.firebaseio.com');
var myDataRef = new js.Proxy(js.context.Firebase, 'https://johnstest1.firebaseIO.com/');
});
This is the same code from main with the line for Firebase Simple Login Added. I have been trying to figure out how to write the code for function(error, user).
js.scoped((){
// var myDataRef = new Firebase('https://johnstest1.firebaseio.com');
var myDataRef = new js.Proxy(js.context.Firebase, 'https://johnstest1.firebaseIO.com/');
//var auth = new FirebaseSimpleLogin(js.context.Firebase(myDataRef, function(error, user){}{}));
var auth = new js.Proxy(js.context.FirebaseSimpleLogin(myDataRef, js.context.function(error, user)));
});
When you want to use Dart callback functions in Js you have to create a Callback and use it as paramter.
The dart equivalent of your first pasted js code is :
var myDataRef = new js.Proxy(js.context.Firebase,
'https://johnstest1.firebaseIO.com/');
var auth = new js.Proxy(js.context.FirebaseSimpleLogin, myDataRef,
new js.Callback.many((error, user) {
if (error != null) {
// an error occurred while attempting login
window.console.log(error);
} else if (user != null) {
// user authenticated with Firebase
window.console.log('User ID: ${user.id}, Provider: ${user.provider}');
} else {
// user is logged out
}
}));
Note : you can avoid js.scoped that is not needed since few versions of js package.
This is some sample code to use Dart to log into Firebase. This combines the answers from Alexandre Ardhuin into one post with some additional code.
The example will:
Get firebase reference and checks to see if user is online
Create a new Firebase user using email and password login
Login into Firebase
Adds a child_added listener and prints any data in the database to the console
Push some data to Firebase and trugger the child_added to display data.
Logout of Firebase
Add the js package http://pub.dartlang.org/packages/js to your program
Add these three lines to the HTML file.
<script src="packages/browser/interop.js"></script>
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase.js'></script>
<script type='text/javascript' src='https://cdn.firebase.com/v0/firebase-simple-login.js'></script>
Put this code in the .dart file.
var YOUR_FIREBASE_PATH = 'https://johnstest1.firebaseIO.com/';
var emailAddress = "emailAddress#xyz.com";
var password = "password";
var myDataRef = new js.Proxy(js.context.Firebase, YOUR_FIREBASE_PATH);
// Firebase
var auth = new js.Proxy(js.context.FirebaseSimpleLogin, myDataRef,
new js.Callback.many((error, user) {
if (error != null) {
window.console.log("Firebase login returned a null");
// an error occurred while attempting login
window.console.log(error);
} else if (user != null) {
// user authenticated with Firebase
window.console.log('User ID: ${user.id}, Provider: ${user.provider}');
} else {
window.console.log("User is logged out");
// user is logged out
}
})
);
Create a new user using email and password to login
// Create a new user using email and password
auth.createUser(emailAddress, password,
new js.Callback.many((error, user) {
if (error != null && user != null)
{
if (!error) {
window.console.log('User Id: ' + user.id + ', Email: ' + user.email);
}
}
})
);
Firebase login.
// Login to firebase
auth.login('password', js.map({'email': emailAddress, 'password': password}));
Add a child_added callback and if a new child gets added to the databes this will get called
// Add a listener for for child_added and gets all the data
myDataRef.on('child_added',
new js.Callback.many((snapshot, String previousChildName) {
try {
final message = snapshot.val();
print("${message.name} : ${message.text}");
}
catch (e) {}
}));
Push some data to Firebase and the child_added callback will print whatever is in the database to the console.
// Push some data to Firebase
myDataRef.push(js.map({"name": 'Mark', "text": 'Works with Dart test 2'}));
Log user out of Firebase
// Logout
auth.logout();
Now there is a dart-team-initiated dart wrapper for Firebase : https://pub.dartlang.org/packages/firebase .
With the usage of Future, dart version is way awesomer than js version.

Categories

Resources