Meteor.user() is undefined when directly access the url - meteor

I have a url http://localhost:3000/test :
Template.test.onRendered(function() {
console.log(Meteor.user());
});
If I first open http://localhost:3000/, then click the test link, Meteor.user() will be printed.
But if I directly open http://localhost:3000/test(Input the url in Chrome's address bar and hit enter), Meteor.user() is undefined.
Why??

That's because Meteor logging in process is not instantaneous upon your app first load, it usually takes a few ms before the user actually gets connected, hence Meteor.user() returning undefined in your template onRendered lifecycle event.
I'm unsure what you're trying to achieve but you can solve this problem by introducing reactivity inside your onRendered handler :
Template.test.onRendered(function() {
this.autorun(function(){
console.log(Meteor.user());
});
});
Declaring a reactive computation using Tracker.autorun will allow your code to rerun whenever the value of Meteor.user() is updated, and particularly on initial logging in resume process.

Related

getRedirectResult is returning null after redirect login

onAuthStateChanged listener fires correctly but getRedirectResult always returns null, even after directly using the login button and trying to use different browsers without a session.
this.auth.getRedirectResult(authUser => {
if (authUser) {
} else {
fallback();
}
});
The above snippet is best context I can give but I'm pretty confident I am using it correctly inside my componentDidMount.
ty
I got the same trouble, too.
I realized that whenever user is null, it emits onAuthStateChanged after the return of getRedirectResult(in the normal case, onAuthStateChanged comes first).
Therefore, I assume there is the same as resolution as firebase.auth().currentUser.
That is to observe on onAuthStateChanged.
refs: https://stackoverflow.com/a/49640188
However, as it is written in the firebase document as follows, this may be a bug.
By using an observer, you ensure that the Auth object isn't in an
intermediate state—such as initialization—when you get the current
user. When you use signInWithRedirect, the onAuthStateChanged observer
waits until getRedirectResult resolves before triggering.
refs: https://firebase.google.com/docs/auth/web/manage-users
The issue was I had imported the firebase scripts while at the same time using npm version. I removed the scripts and everything is working as should. The time delay between redirect and the call to getRedirectResult is still ridiculous though.

In Meteor, how to short-circuit-assign a helper variable with user object?

I'm running the latest Meteor (v1.1.0.3) on OS X 10.6.8 in Firefox 39.0.
I'm using accounts-ui and accounts-google for login management. I have a hand-rolled profile form with (among other things) a 'name' field. The initial value of this field should be either the name that is already set in their profile or the one that Google supplies.
I've defined the following template helper:
Template.profile_edit.helpers({
my_name: (function () {var u=Meteor.user(); return u.profile.name || u.services.google.name;}())
});
I use the value in my template as {{ my_name }}. When I start meteor everything compiles just fine, but when I load the profile page I get the following Javascript error:
TypeError: u is undefined
...me: (function () {var u=Meteor.user(); return u.profile.name || u.services.googl...
Not immediately relevant, but just for completeness:
After the page loads, the 'name' field in the form is blank.
I am logged in.
When I pull up Meteor's mongo instance in my terminal I can see my user record; the name in the profile is NOT set, the name in the services.google.name IS set.
Why is this error happening and how can I solve it?
The Problem
This is a common issue that people have when first starting out with Meteor. The problem is that when this helper is executed during page load, depending on the response time for the publication from the server, the data for the currently logged in user may not be available yet. This makes it seem intermittent because at times the data is published in time, and others it's not.
Possible Solutions
One possible solution is to install meteorhacks:fast-render. This will publish the logged in user (due to the null publication) with the initial html for the page and guarantee that the user is available when this helper is run. Data other than the currently logged in user will need to be properly set up as subscriptions on the router for fast render to take effect.
The other solution, and one that will work without installation of a new package is to guard against undefined. This will effectively let the helper return undefined when there is no data, but once the data is available the helper will reactively rerun and the proper data will be returned.
Template.profile_edit.helpers({
my_name: function () {
var u=Meteor.user();
if(u){
return u.profile.name || u.services.google.name;
}
}
});
Aside
In your helper I notice that you are using syntax like my_name:(function(){}()). While this will give you what seems like a desired outcome, the problem is that you are immediately invoking this function and assigning its value to the my_name helper instead of assigning it a function that can be called multiple times when the value changes. This breaks reactivity and so the second solution would not work due to it's reliance on it.
Template.profile_edit.helpers({
my_name: (function () {
/*
This is immediately invoked and basically
like using my_name: "bob"
*/
}())
});

MeteorJs "loginWIthPassword" seems not to work in method

It seems that the "Meteor.loginWithPassword" function does not work when called in a method.
I want to create my login form with autoforms and so I created a callback method which get called after a user submitted the login form. The form gets called the right way but the loginWithPassword function does not seems to work.
This is my method (on Client & Server side)
Meteor.methods({
autoform_test_login : function (doc) {
console.log('Called login method');
if (Meteor.isClient) {
Meteor.loginWithPassword('test', 'test', function(e) {
if (e) {
console.log(e);
}
});
}
}
});
My autoforms calls this method when submitting with:
{{#autoForm schema="Schema_Login" id="form_login" type="method" meteormethod="autoform_test_login"}}
....
When submitting this form I get this error:
Error: No result from call to login {stack: (...), message: "No result from call to login"}
When I now open my Browser console and type in:
Meteor.call('autoform_test_login');
I will get the same error.
But: When I type the following in my console it works (The error now is: Username not found):
Meteor.loginWithPassword('test', 'test', function(e) {
if (e) {
console.log(e);
}
});
My method do absolutely nothing else then this snipped so I am asking myself whats going wrong here.
Ps.:
I know that I added the "test" as Username and "test" as password - its just to test. Even when the input is the right the error is always the same.
Okay, so I got a response and now I know why this is not working as expected.
loginWithPassord may only be executed on the client.
When you use Meteor.methods on the client, it will still run the functions you define within it on the server. That is why it won't work to have the loginWithPassword call within a Meteor.methods function.
Simply use this function anywhere else on the client. For example - directly within some template event.
Took me like forever to find out why it wasn't working.
Make sure that autoform is actually passing the correct values. If you've made a mistake in you're schema setup it will automatically clean the values (set to undefined) without throwing an error.
I'm also not entirely sure if using it with method set will work in this case, as you want to do the login call on the client not the server (I think).
Make sure your current Meteor instance has an active connection with the mongo database pointed to by variable MONGO_URL. Meteor.loginWithPassword fails to give error feedback when this connection gets closed or broken.

What triggers an onAfterAction in IronRouter other than a route change?

I'm having trouble debugging an onAfterAction that I don't want to run. It happens when I click a certain div. Router.go is not being called (verified with debugger; in the iron router code), and the URL is not changing. I can't find anything in my click handlers that would cause a route change. The onAfterAction happens from a deps invalidation:
Router.configure.onAfterAction (routes.coffee:5)
RouteController.runHooks (route_controller.js:155)
(anonymous function) (route_controller.js:291)
RouteController.runHooks (route_controller.js:158)
(anonymous function) (route_controller.js:283)
Deps.Computation._compute (deps.js:196)
Deps.Computation._recompute (deps.js:210)
Deps.flush (deps.js:304)
Probably you have some reactive data source in onAfterAction (cursor, Session object).
It will rerun every time reactive data source will be changed.
You can forbid this behavior by wrapping function in onAfterAction :
Tracker.nonreactive(function(){})
Clicking the div caused the User doc to change. There was global onBeforeAction that checked to see if the user was logged in (if Meteor.user()), which is reactive and triggered a rerun of action and onAfterAction. I changed it to if Meteor.userId(), which did not get invalidated when updating the user doc.

How to get logged-in user email in publish functions in meteor?

I've created a meteor 0.5.4 app - added accounts-ui, accounts-password, and added {{loginButtons}} to the template name="hello" block hat comes stock with every meteor create.
When I type this in a chrome browser console, Meteor.user().emails[0].address as per these SO sources - http://goo.gl/MTQWu, http://goo.gl/Cnbn7 - I get the currently logged in users email.
When I attempt to put the same code within the if (Meteor.isClient) section :
Template.hello.greeting = function () {
return Meteor.user().emails[0].address;
};
I get :
Uncaught TypeError: Cannot read property '0' of undefined foo.js:3
Exception from Meteor.flush: TypeError: Cannot call method 'firstNode' of undefined
If you can't place Meteor.user() within publish functions, how else can I get the email of the logged in user? I've tried making it a shared function, and calling it within the client side function with Meteor.call('getEmail', Meteor.userId()) with similar results.
Templates are reactive. That means that when the page loads, the template is run, and it will be run again when its dependent data source changes. In your case, the first time it runs, Meteor.user() isn't ready yet, so it has no emails attribute yet, which causes an error. To fix this you need to check whether the user object exists yet:
Template.hello.greeting = function() {
var user = Meteor.user();
if (user && user.emails)
return user.emails[0].address;
}
To get the current user inside a publish function, use this.userId.

Resources