How to call .isNewUser() in authStateObserver in firebase - javascript

Its not at all clear in the documentation how to check if a freshly logged in user has logged into my web app previously. There is an isNewUser() call referenced here:
AdditionalUserInfo
What is not clear is how to get access to this call when using a firebase auth call and observer.
firebase.auth().onAuthStateChanged(authStateObserver);
The authStateObserver gets a user object after the person logs in using the provider specified. This user object cannot be used to call .isNewUser() so how does one get to the additionalUserInfo which has the call to .isNewUser() from inside this authStateObserver? This is in javascript in a web app.

firebase.auth().onAuthStateChanged only triggers with the FirebaseUser. You can't get additionalUserInfo or any credential eg. OAuth tokens associated with the result from that observer. You have to get it from the firebase.auth.UserCredential after the sign-in promise resolves.
As these results are only available once on sign-in and Auth does not refresh OAuth credentials or actively update underlying OAuth profiles, Firebase Auth opted not to provide them in onAuthStateChanged listener as it could mislead developers to think that the listener can be used to listen/get new credentials or additional user data when in reality this information is only available once on sign-in.
The observer will only observe changed to the FirebaseUser, eg. sign-in or sign-out events.

For isNewUser(), go into the FirebaseUser class, click on the child class, it should take you to class zzn (for Android & as of now). Search for "isNewUser", you will find a field tagged with that string. It is zzj:
#Field(
id = 10,
getter = "isNewUser"
)
private boolean zzj;
Now search for the getter of that field, in my case it is:
public final boolean zzj() {
return this.zzj;
}
So in your code base, this is the condition: ((zzn) firebaseUser).zzj()
All you have to do is follow the Zzzzz letters. Smh (painful naming).

Related

Method to check if ActionCable subscription for given channel already exists on js consumer side?

I want to add consumer subscription when modal is opened because only in that case I need to receive some channel messages. I know I can list subscriptions with consumer.subscriptions and there's an array of identifiers returned, but is there any js method to check if given channel is already subscribed, sth. like consumer.isSubscribed('FooChannel') ?
You can create the subscription, only when the modal is open and avoid the unnecessary check. Alternatively, you can utilize subscriptions#findAll to implement the isSubscribed method
consumer.subscriptions.isSubscribed = function (channelID) {
return this.findAll(channelID).length > 0
}
findAll is defined here

MobX - how to comunicate between stores?

In my application i have two MobX stores - store_A for handling user information (who is currently logged, etc), and store_B for handling events for all users.
After user login, i want to display all events regarding that user.
How can i access logged user info (from store_A) from within store_B so that i can filter events correctly?
At this point i have to store loggeduserName data inside my store_b to retrive that data...
Code from my events store:
class ObservableEventsStore {
...
//after logIn, save userName:
#action setUser(userName) {
this.givenUser = userName
}
...
#computed get filteredByUser() {
let filteredByUser = this.wholeList
.filter((event) => this.givenUser === event.user)
// this.givenUser is what i want to get from store_A
return filteredByUser
}
I want to get loggedUser data from UserStore, i have it stored there as well ...
There is no idiomatic approach, any means to obtain a reference to the userStore is valid. I think in general you can take three approaches to achieve this:
construct the userStore before the EventStore and pass the reference to the EventStore in it's constuctor (or set it afterwards)
If the UserStores is a singleton, just import and use it
Use a dependency injection system like InversifyJS

Meteor: Tracker.autorun isn't running on user collection change?

I'm using this package to manage Facebook data as Collections in Meteor. Since a FacebookCollection can't be defined until the user is logged in with Facebook, this ticket describes a method to do so automatically; I've been trying it like so:
/lib/collections.js
Tracker.autorun(_.bind(function(){
var user = this.user;
if (user && user.services && user.services.facebook && !Friends){
Friends = FacebookCollections.getFriends("me",["id","name"],100);
}
}),this);
Using some log statements, I see this run only once, early on when user is still undefined, but never again. I suspect that this isn't being re-run because it's not referencing a reactive data source, i.e. the User collection, but I'm not quite sure what to do here to get this to work.
Note: the example in the ticket uses Meteor.user(), however, this gives the error:
Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.

Angular JS + user authentication + page refresh

So this is my problem.
I can successfully login from my angularJS app using the auth factory i made that communicates to my pp rest API.
lets say Auth.login(user) -> (POST) myapi.com/user/login: the response is the user object that Auth saves locally. Thus Auth.getCurrentUser() returns local user object.
my rest API, i also have a myapi.com/user/get_loggedin_user which returns the current logged in user (using the php session). So if Auth.getCurrentUser should actually check if local user exists, if not do an ajax to myapi.com/user/get_loggedin_user and check if logged in before responding with null. One problem here is, ajax is annoying like this, you would then need to put in a success callback function and have all your code execute inside the success callback.
Now lets say im on the Angular App (website), mydomain.com/user/dashboard (already logged in), and then i refresh my browser. Now, when the page reloads, angular does not know my current user, so before it redirects me to mydomain/login, i want it to check if the user is logged in. i can obviously do a 1 time call within the controller, but is there a more easy way where i can register within a controller with some access restrictions (Eg: logged_in == true), and when you visit any page with logged in requirement, it checks local user (gets the user if does not exist), and redirects to login page if null, or display the page once it matches the requirements?
Different common page requirements: null, logged_in, admin, function: haveAccess(user, object).
NOTE: im using stateProvider
If I understood your question correctly, you are asking about how to check whether the user is logged in before the controller is invoked, and to avoid the check for a logged-in status in each controller that needs it.
If so, you should look into the resolve parameter - this exists both in $routerProvider and $stateProvide.
Essentially you could "resolve" your loggedInUser variable (by doing whatever you need to do via your MyAuth service.
Here's an example of what I mean with $routeProvider:
$routeProvider
.when("/someSecuredContent", {
templateUrl: 'someSecuredContent.html',
controller: 'SecuredController',
resolve: {
loggedInUser: function(MyAuth){
return MyAuth.loggedIn(); // MyAuth.loggedIn() should return a $q promise
}
}
});
Then in the controller, loggedInUser will be injected.
Here's a site with more examples.
Correct me if im wrong:
Do this within the Main Controller (make sure you inject the dependancies like rootScope, state, and your own Authfactory)
$rootScope.$on('$stateChangeStart', function (event, next, toParams) {
if (needToBeLoggedIn()) { //use the next object to read any data, and you can set on the state some flag
event.preventDefault()
MyAuth.loggedIn(function success(){ $state.go(next,toParams); }, function err (){/*send somewhere else*/});
}
})
Put logged_in = true to cookieStore in your login method after authentication as below.
$cookieStore.put('logged_in',true);
$rootScope.logged_in = true;
and in your Controller, do
$rootScope.logged_in = $cookieStore.get('logged_in');
Now you can use this logged_in variable anywhere in the UI to check if the user is logged in.
Make sure to use 'ngCookies' module in your app. and pass the $cookieStore dependency to your controller. You can even keep the user object itself similar to logged_in variable in cookies and retrieve it from cookies.
Make sure to do logged_in = false and clear other variables in cookies and set it to blank in your logout method.

How should I update user.profile on subsequent login (something similar to Accounts.onCreateUser)?

I've been poking around in the Accounts packages, using a modified version of the ever-fabulous EventedMind Customizing Login screencast.
I modified it to use facebook instead of github, and I noticed something when trying to update user.profile information. Specifically, I'm looking for the right way/place to handle changes to user.profile.
Let's say, for example, that I authenticate as a FB user for the first time. When I do this, the CreateUser event will fire.
Using Accounts.onCreateUser(...), I can populate additional information from the FB graph into the profile, like so:
Accounts.onCreateUser(function(options,user){
var accessToken = user.services.facebook.accessToken,
result;
result = Meteor.http.get("https://graph.facebook.com/"+user.services.facebook.username, {
params: {
access_token:accessToken,
fields: ['picture', 'name','first_name','last_name','username','link','location','bio','relationship_status','email','timezone','locale']
}
});
if (result.error){
throw result.error;
}
user.profile = result.data; //lazily adding everything
return user;
});
This works just fine when the user is created. It's nice and clean.
But now let's say that some of the information changes. For example, let's say that the profile picture changes. If I log out and then back in to the meteor application, Accounts.onCreateUser(...) doesn't fire, because the user already exists. It's not being created again, it's being modified.
I need to update the user.profile on subsequent logins, or at least check for changes and then modify as needed. I'd ideally like to do this in similar fashion to .onCreateUser. Maybe with a .onModifyUser or something...
I can figure a couple of ways to do this using some checking and/or client-side code, but I'm wondering if there is an already-existing server hook that would be cleaner.
Any recommendations on the cleanest way to handle this situation?
Thanks in advance.
If you're manually calling the login functions you can pass a callback as the last parameter which will get called on the client after the login completes. See: http://docs.meteor.com/#meteor_loginwithpassword.
Meteor.loginWithFacebook({}, function (err) { /* make a Meteor method call here */ });
There are no documented server side callbacks at the moment.

Categories