Exception from sub books id dMBTck6CaSupWbEna TypeError: Cannot read property ‘emails’ of null - meteor

I am getting an Exception whenever a user logged in into his account, and I cant see the collection data until the page is been refreshed… **[but I am not getting any exception if I use it like
Books.find({“customer_name”:this.userId);
instead of
Books.find({“customer_name”:Meteor.user().emails[0].address);
and I don't need that step because in my app users collection finding should be based on their email id, not by userId…]**
my code is shown below :
Someone, please help me out:frowning_face:
server - main.js:
var My_collection;
Meteor.publish(‘books’, function() {
My_collection =
Books.find({“customer_name”:Meteor.user().emails[0].address);
return My_collection;
client -main.js:
Template.viewBooks.helpers({
books() {
return Books.find({}, { sort: { books_order: -1 } }).fetch();
},
});
client - main.html
{{#each books}}
{{books_id}}
{{/each}}
ERROR:
App running at: http://localhost:3000/ I20171205-16:06:49.773(5.5)?
Exception from sub transactions id wQ9DpjjABEiPzMZ9P TypeError: Cannot
read property ‘emails’ of null I20171205-16:06:49.872(5.5)? at
Subscription._handler (server/main.js:16:75)
I20171205-16:06:49.873(5.5)? at maybeAuditArgumentChecks
(packages/ddp-server/livedata_server.js:1768:12)
I20171205-16:06:49.873(5.5)? at
DDP.CurrentPublicationInvocation.withValue
(packages/ddp-server/livedata_server.js:1043:15)
I20171205-16:06:49.873(5.5)? at
Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1134:15)
I20171205-16:06:49.873(5.5)? at Subscription.runHandler
(packages/ddp-server/livedata_server.js:1041:51)
I20171205-16:06:49.873(5.5)? at
packages/ddp-server/livedata_server.js:826:41
I20171205-16:06:49.874(5.5)? at Function..each..forEach
(packages/underscore.js:147:22) I20171205-16:06:49.874(5.5)? at
packages/ddp-server/livedata_server.js:822:9
I20171205-16:06:49.874(5.5)? at
Meteor.EnvironmentVariable.EVp.withValue (packages/meteor.js:1134:15)
I20171205-16:06:49.874(5.5)? at Session._setUserId
(packages/ddp-server/livedata_server.js:816:34)

It’s generally bad practice to use Meteor.user() on the server. Without having enough information surrounding how you’re publishing and subscribing to your collections, and since you’re saying you aren’t getting any errors when you use this.userId, you can find the email address the following way:
var currentUser = Meteor.users.findOne(this.userId);
var userEmail = currentUser.emails[0].address;
Then use it in Books.find
If you can provide more information about the subscription and the publication, i’d be able to help out more

Related

Firebase user.delete() method works but with error

I am using angular, and have an application that stores user details, and login info. When trying to delete a user, I am first deleting all the user related information. Then asking the user to re-authenticate themselves, after authentication, user gets logged out, and their basic details fetched to show profile id deleted followed by their sign-in info using user.delete().
All this works as expected, but at the end I am getting an error. Why am I am getting this error even when I have already logged out the user of the application.
Error Message: {code: "auth/user-token-expired", message: "The user's credential is no longer valid. The user must sign in again.", a: null}
My code -
deleteAccount(){
var userToDelete = firebase.auth().currentUser;
this.logout();
this.store.dispatch(UI.StartAppLoad({status:'Deleting User Details...'}));
this.userService.DeleteUser(userToDelete.uid)
.then((res)=>{
console.log(res);
}).catch(this.HandleError.bind(this));
userToDelete.delete().then(
(res)=>{
console.log(res);
this.uiService.showSnackbar('User Account Deleted',null,3000);
this.store.dispatch(UI.LoadApp());
}
).catch(this.HandleError.bind(this));
}
logout() {
this.afAuth.signOut();
}
where, HandleError is used to display the Error Message in a snackbar.
deleteAccount() is called after the user successfully authenticates themselves.
Instead of getting the error message displayed, I want to display the message 'User Account Deleted'.
Entire Flow -
onDeleteAccount(){
const confirmResult = this.uiService.showConfirm({
isDanger:true,
title:'Delete Account?',
content:'All your user account data will be permamnently deleted.'+
' You will need to create a new account later. Are you sure you want to continue?',
okText:'Delete'
});
confirmResult.subscribe(async isDelete=>{
if(isDelete){
this.store.dispatch(UI.StartAppLoad({status:'Deleting Excercise Data...'}));
const isResetDone = await this.trainingService.resetPastExercise();
if(isResetDone){
this.store.dispatch(UI.StartAppLoad({status:'Deleting Follow list...'}));
this.userService.clearFollowList();
this.authService.actionToPerform.next(actions.Delete_Account);
this.store.dispatch(UI.LoadApp());
this.router.navigate([AppRoutes.ReAuthenticate]);
}
}
});
}
Authenticate Page's submit() method:
this.authService.reauthenticate({
email:form.value.email,
password:form.value.password
});
this.authService.deleteAccount();
AuthService:
reauthenticate(authdata: AuthData) {
this.store.dispatch(UI.StartLoading());
var credential = firebase.auth.EmailAuthProvider.credential(
authdata.email,
authdata.password
);
this.afAuth.currentUser.then((user) => {
user.reauthenticateWithCredential(credential)
.then((res)=>{
this.prevPwd = authdata.password;
console.log(res);
this.store.dispatch(UI.StopLoading());
})
.catch(this.HandleError.bind(this))
});
}
And then the above method deleteAccount()
Please suggest.
As explained in the doc, this happens because:
delete() is a security-sensitive operation that requires the user to
have recently signed in.
The doc also indicates that:
If this requirement isn't met, ask the user
to authenticate again and then call firebase.User.reauthenticateWithCredential.
So, you need to handle this specific error and do as indicated by the doc, i.e. "ask the user to authenticate again and then call reauthenticateWithCredential."

Trouble returning a valid result while integrating Stripe API into my Meteor app

Here's the rundown:
I'm trying to run Stripe API on my Meteor app asynchronously
Long story short, everything works (i.e. subscription and charge is/are created normally and shows up in my Stripe dashboard)
When errors occur, the errors throw normally and show on client via user friendly alerts
I have a problem when there is a success and customer subscription is created, the result is not present in client and instead always returns as an error, despite it being a successful process
Here's what my method looks like on the server:
createCustomer: function(token, email, plan){
try{
let createCustomer = Meteor.wrapAsync(stripe.customers.create);
let result = createCustomer({
source: token,
email: email,
plan: plan
});
let subscription = {
customer: result.id,
sub: result.subscriptions.data[0].id,
plan: result.subscriptions.data[0].plan.name
};
Meteor.users.update({_id: Meteor.userId()}, {$set: subscription});
} catch(error){
if(error.code === "incorrect_cvc"){
throw new Meteor.Error("incorrect_cvc", error.message);
}
// More of such errors follows
}
}
Here's what it looks like on the client:
Stripe.card.createToken({
number: number,
cvc: cvc,
exp_month: exp,
exp_year: exp_year,
address_zip: zip,
address_country: country
}, function(status, response){
if(response.error){
console.log("Make sure all fields are filled before submitting order.");
} else{
let token = response.id;
Meteor.call("createCustomer", token, email, plan, function(error, result){
if(result){
console.log("Congratulations, everything worked!");
} else{
if(error.error === "incorrect_cvc"){
console.log("oops, the CSV is incorrect");
}
// More of such errors follow..
}
})
}
});
So, everything works in terms of when there is a real error, it throws fine on server + client. When user uses card, the charges are created and subscription is always created. HOWEVER, when there is a success and everything clicking fine, I still receive an error on client via callback and the result is never true or triggered. No idea why.
Not 100% up on Meteor, but it looks to me like your createCustomer method doesn't actually return anything, so the result from your (err, result) might never have anything in it?
As was mentioned in the comments, you might want to separate out the steps and wrap each in its own try-catch set so you can better isolate the issue.
Also, I feel like you could probably generalize your server-side error code to something like:
throw new Meteor.Error(error.error, error.message);
And I might even be tempted to do something like this, at least during testing/development - that way you can actually console.log() the original error in the browser:
throw new Meteor.Error(error.error, error.message, JSON.stringify(error));

Firebase's Angularfire not firing catch on $signInWithEmailAndPassword

When calling any of the AngularFire samples,I'm getting responses from the server, but methods in then & catch are not firing
Html:
script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js">/script>
script src="https://www.gstatic.com/firebasejs/live/3.0/firebase.js">/script>
script src="https://cdn.firebase.com/libs/angularfire/2.0.0/angularfire.min.js">
Javscript:
// Factory from example
myApp.factory("Auth", ["$firebaseAuth",
function($firebaseAuth) {
return $firebaseAuth();
}
]);
// Function called from inside controller
Auth.$signInWithEmailAndPassword("my#email.com", "password").then(function(firebaseUser) {
console.log("Signed in as:", firebaseUser.uid);
}).catch(function(error) {
console.error("Authentication failed:", error);
});
I'm unable to get the then or catch logic to fire. Instead the output is:
firebase.js:75 Uncaught Error: There is no user record corresponding
to this identifier. The user may have been deleted.
Should the .catch portion be where this is caught. I had this working in the old firebase, but I recall it not always being reliable there as well.
Looks like there was a bug in AngularFire 2.0.0 lib. Try to import 2.0.1.
<script src="https://cdn.firebase.com/libs/angularfire/2.0.1/angularfire.min.js"></script>

Meteor custom login procedure

This Meteor app has the insecure and autopublish removed and accounts-ui accounts-password added.
The code below needs to get the username and password, send them the to server which will run a method validateUser that returns true if valid.
validateUser tries to login to another server on the web, and returns true if successful, then my code should create a user account for this user.
The app is crashing because of this line
Accounts.createUser(useername: digest[0], password: digest[1]);
But even if it does not, Is this the meteor way to get this particular task done? Thanks
Edit:
After adding {} to the problem line in order to pass an object as suggested in the comments, I now get this error printed in the terminal;
Exception while invoking method 'logMeIn' Error: Match error: Failed Match.OneOf or Match.Optional validation in field password
<template name="myLogin">
<input type="text" name="username">
<input type="text" name="password">
<button id="logMe">log me in</button>
</template>
Template.myLogin.events({
'click #logMe': function() {
var credentials = [$('#password').val(), $('#username').val()];
Meteor.call('logMeIn', credentials, function(err, result) {
if (result) {
console.log('logged in!');
}
});
}
});
// on the server
Meteor.methods({
logMeIn: function(credenticals) {
//do work , if logged in, do next line
console.log("user account created");
Accounts.createUser({useername: credenticals[0], password: credenticals[1]});
}
});
Match error: Failed Match.OneOf - is because this method checks if email or username is presented in the object you are passing. You have typo in username and don't have email.
Next thing you are saying, after fixing typo you get Exception while invoking method 'logMeIn' Error: Match error: Expected string, got object in field username
This is because you have array with two undefined "members". Look at your jquery selectors. You are trying to select by id # but have inputs without ids.
Please organise yourself.
Your line
Accounts.createUser({useername: credenticals[0], password: credenticals[1]});
Has two typos, it should be
Accounts.createUser({username: credentials[0], password: credentials[1]});

Meteor: Resend email verification link

I want to be able to resend an email verification link to users of my Meteor application in case they accidentally delete their email verification email.
I have a link with the id "resentEmailVerificationLink"
I have the following code in my client for when the link is click (alerts are just there to show myself how far the function gets before an error):
Template.dashboard.events({
'click #resentEmailVerificationLink' : function(event) {
event.preventDefault();
var id = Meteor.userId();
alert('clicked: ' + id);
Accounts.sendVerificationEmail(id);
alert('Verification Email resent');
return false; // Stops page from reloading
}
)};
I know the sendVerificationEmail is a server function but I have no idea how to call this function in the server upon clicking the verify email link (I'm a bit of a Meteor newbie).
Any idea of how to accomplish this, because currently it doesn't work with the following error: Uncaught TypeError: Accounts.sendVerificationEmail is not a function
Note: Meteor.Accounts.sendVerificationEmail(id); doesn't work either (it does however produce a different error.
You can try with server side method just create one pass the attrs and call http://docs.meteor.com/#/full/accounts_sendverificationemail on the server. More about meteor methods: http://docs.meteor.com/#/full/meteor_methods

Resources