I am not sure what code I need to share but it appears so that every-time I login, my firebase-functions session is maintained across that very tab, meaning if in my browser, I have logged in through one tab and open a new tab, i need to login again.
How can I make my firebase function session consistent i.e if open in one tab, I don't need to open across another tab.
This is thread which seemed relevant but it's been some time since OP posted it.
https://groups.google.com/forum/#!topic/firebase-talk/zkrJsCh0_sw
If I'm interpreting your question correctly, you
have a Firebase app that allows users to log in, and
you want a logged-in user to be able to open a new tab, and automatically be logged in there as well
You can do so by adding the following line to your front-end code, at a place where the Firebase SDK is initialized and available:
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL);
Instead of LOCAL at the end, the other two options are SESSION and NONE, each of which gets progressively more restrictive with how it allows users to remain logged in.
Note that LOCAL is the default, so you may wish to check whether this setting has already been changed elsewhere in your code.
Note also that the capital letters are correct.
You can read more about the options and see a more detailed example of how to implement this code at the official Firebase docs on persistence
If that's not what you're asking about, you may wish to consider clarifying your question to indicate how my assumption 1. or 2. are incorrect. Cheers!
Related
Is this a common/reasonable Use case?
An app allows a user to save favorites locally so that the user doesn't need to signup.
Then the user afterwards desires to share their favorites.
Therefore favorites data needs to be synced from local to remote. The usual local storage for flutter is sqflite, and firebase/store is the remote. However, this seems cumbersome, as sql to nosql conversion is necessary.
I thought that this would be a general issue for UX etc, but I can't find any discussion of this issue? Maybe forcing the user to create an account is the most general solution?
It's a common understanding that if you don't have user account then you can't have any user data associated with your name. You don't have to force the user to have an account or lock them out.
When they favourite something just show a dialog telling them "If you don't have an account your favourites are stored on the device only. If you want your favourites to be available everywhere please create an account" then show options for "Create account" or "No, Thanks"
Create account: Goes to account creation page
No, Thanks: Adds the device to the favourites list and lets the user continue to do what your app does.
There's no problem to solve here from what I'm seeing. If you don't have an account you don't get account functionality. If you track users without them entering anything it's also a little bit illegal and creepy so no need to push the limits on how you can track the same user.
Another way to think of it is to make signup so easy they don't mind and also guarantee that it's worth it. Won't be used for spam or information selling. Take what's app as an example, even though you need to mobile number to send the messages, it's just used as a unique identifier and has nothing to do with the device's number.
Ask for their phone number or email or just any email, you'll most likely get fake info.
And what does your analytics say? Are you getting requests from users saying they lost all their information on a different device? How many people are using your favourite functionality?
I may have come to the party a little late here but here's my 2 cents worth.
The Sql to NoSql conversion is not cumbersome. In fact, there is a reasonable use case for this. I have the same requirement for an app that I am about to build.
Anyway, to store data in RDMDB or NoSQLDB you will need a data model to ensure consistency in your app. If the user has been using the app offline, and they later choose to go online, you can allow them to create the Remote Account, then check if they have local favorites. If they do, you will HAVE to ask them if they'd like to import them into the remote storage. If they choose to do so, you will then have to read their favorites from the local storage and store them in a List<Model> then map() that back to the online storage.
NoSqlDB can accept the json type data, so your model should include the conversion fromMap() and toJson() for this purpose (and others).
When I have come around to doing this, I will share my code (if I remember to come back here).
Update: Due to code refactor, the need for testing that has gone away, and as Ron pointed out in the accepted answer, onAuthStateChange() will fire eventually, and the app can rely on that. I wasn't originally seeing that, which is what motivated my question.
Original Question: I've been using window.localStorage and searching for a key that starts with 'firebase:authUser' as a way to determine if my app can expect a firebase authentication event any time soon. Whether it succeeds or fails, firebase.auth().onAuthStateChanged() is triggered, and I can deal with the result there. The reason for wanting to know is that if I have some local credentials which are being processed, my app can display a 'Please wait...' type message. But if there are none, it can redirect immediately to the login page. Since firebase moved to indexedDB, this code no longer works, and I couldn't find any equivalent hack to look for locally persisted credentials (maybe it's not possible now?).
I'd also be happy to switch to SESSION persistence rather than LOCAL, but I'm not sure if this changes the scenario at all—I'd still need a way to test if there was anything happening to avoid the user being stuck at the 'Please wait...' message forever if there were no local credentials to validate.
Or am I doing this wrong? I know I could show the login page until firebase.auth().onAuthStateChanged() fires, but by then the user might have clicked, and the experience isn't that great either if they already signed in and then refresh the page, where they see the login page again until everything is loaded.
I couldn't find anything in the auth() API to tell if it was in the process of dealing with locally persisted credentials, and up until now, the window.localStorage hack has been working very well. What's the best way to manage the user experience now?
You could grey out inputs and disable submit button until .onAuthStateChanged resolves which happens very quickly, usually in under 1 second. Maybe put a linear progress indicator on the login form?
Relying on underlying implementation is never a good idea instead of provided public API. Firebase has the right to change that at any time. They could have even persisted the user with a different format and that would break your implementation.
That said, you can easily bypass this, by setting your own flag in localStorage when a user logs in and remove it when they sign out. This is better than relying on the hack you had. In this case, you have full control over that flag. You set it anytime a user is signed in after onAuthStateChanged is triggered and remove it on sign out. When a page is loaded you read that value directly to know whether to display the progress bar or not.
So I'm building out an app with Meteor and noticed when I log in with Twitter and then Facebook, I create two separate user accounts. Is there any built in way to make sure these are merged? I'm not seeing any email address in the twitter based user account, so I can see it might be difficult to figure out which accounts to link.
Suggestions? Thanks!
I've been in a similar situation so here's a good starting point for you:
You might want to do the merge at the Accounts.onCreateUser event. Basically, what you would do at this time is to:
Do a mandatory protocol / routine to save the email in some profile field in any authentication method as much as possible, so that you are able to do the next step, which is..
Whenever another authentication method is used (to create the user), you can compare the existing database of users (now confident that an email field would be present at all times to check against), and do the merge whenever an exact email match happens.
It's a shame I do not have the code now because I tried this protocol once, but I quickly decided that I'll just stick with one authentication method for some reason. Maybe I'll update this answer when I can get around to try and code that again.. or maybe not.
We have a client that is using Cart66 on their site. They want the option to accept checks and ship COD but only want admin users to have the ability to perform manual checkout, but in order to track a customers order history they want to place all orders through the site as the customer.
I guess my question boils down to this: is there a way to log in as an admin user then switch to a non-admin user yet keep admin privileges? They are wanting to switch to a regular user but keep the admin ability to manually check out.
They could switch the user to an admin, perform the transaction, then switch the user back to subscriber. Is there another way to keep admin privileges without these steps?
I hope that makes sense. If there is anyone out there that can point me in the right direction I would greatly appreciate it.
Thanks
Honestly, no. I've gotten around this by opening two different browsers. I.e. I'll create two users: the admin account (my normal account), and then an alternate (test) account that's set as a subscriber. I'll use my regular browser and log in as an administrator (my usual account), and then open an alternate browser, and log in as the test account. So I'll have 2 windows open, but each window has a different account open in it. Works just fine. I get to see everything that happens as and admin and a subscriber at the same time.
It would be cool if you could do something like you're describing though - but I can see why you can't - you're getting into user roles and capabilities that would make no sense if you could do what you're describing.
I suppose one possibility would be to use the current logged-in-user's ID, and write a function that would strip front-end capabilities (visually make them appear to be a logged-in subscriber), but it's a lot easier to just open two different browser windows.
The reason I'm asking is because, right now we already have it setup to prompt users to share things if they're connected. But the biggest problem we have is that without the user being connected, it tries to make a popup window — which is blocked in most browsers. (vs. the iframe inline)
So, I'm trying to see what the benefit or difference in us implementing the new changes if we're already doing "timeline-like" sharing. I don't get it? Do we have to recode everything?
Last, off topic, but I'm confused about the way the referral API works actually, because the same code doesn't seem to invoke the API at all. Just display the user's name
You need to get the users "publish_actions" permission to add things to timeline. So in that sense, yes, they do need to be connected. But the advantage of that is that once you get "publish_actions" permission, the user never needs to be prompted... you just automatically share the actions they've taken by making api calls.