Is local state management really needed when using firebase? - firebase

(this was originally a post on the flutter-dev reddit that was redirected here)
So I started making this flutter app using firebase as a backend and after looking at all the options for state management I finally realised that the tools provided by firebase already handle pretty much everything I would need state management for.
For example:
I could set the currently logged in user in my state to show the right login or home page and make the user uid available to widgets for their firestore API calls.
OR
I can just listen to FirebaseAuth.instance.onAuthStateChanged to show the right page and just use FirebaseAuth.instance.currentUser() from anywhere to get the logged in user uid and do my firestore calls.
What I mean is, for every thing that would require global state, I can just basically have a firebase stream listener.
Is this right ? Or am I missing something here ?

You're not missing anything. Since most Firebase APIs rely on data from Google's servers, many of them are designed to be used in a reactive way. Making your UI reactively respond to those asynchronous changes is (in my experience) the best way to keep your code simple.
There may be slight behavior between the different types of listeners. But the onAuthStateChanged listener immediately fires with the current state when you attach it, which makes it a good example of a listener that you can use everywhere you need to respond to auth state (instead of also storing that state somewhere in your app).

In that scenario I would say yes, you can read the onAuthStateChanged stream and react to changes. But there are also scenarios where I need a stream for interacting between widgets without a parent/child relationship. For example, in one of my apps I have a company selector, and the rest of the app reflects to the selected company. I created a stream, so that the company selector doesn't need to be a parent of the other widgets, and especially so that I don't need to pass the company parameter to all the widget tree.
I also have one scenario where I need to load extra information about the user that isn't available on the FirebaseUser object. So when the user is logged on I load their information from a "users" collection and then I add that to a custom stream.
So to conclude I would say yes, you should use the default Firebase streams when possible, but that doesn't mean you can or should use that solution for everything.

Related

Firebase dynamic link lifespan

I create Firebase dynamic links programmatically and can share them with other application users (I invite them to join some of my entities, for example). But here is the problem: users are able to resend the link to other users and I am not able to control it.
Is there any mech to make dynamic links disposable (one-off) or adjust the link with some lifespan timer? How do you handle the case when you want to control the link distribution?
I've checked Firebase documentation and it's said that the dynamic link can not expire.
I suggest that you consider checking this step and the succeeding ones as these demonstrate how you can create a referral link up to the retrieval of the UID value. If you have generated a short link, this might be the next steps you’ll want/need to implement with your client application code.

Implementing a notification system for sending/accepting friend request using firebase cloud functions and firestore

I am trying to implement a notification system for handling notifications similar to friend request notifications. For example, I write the email of the person I want to send a friend request to. then click on send request. I am confused as to after that, what exactly should happen?
Right now I am thinking that on clicking send request, I would create a document in cloud firestore in a 'notifications' collection, which would then invoke a cloud function that sends a push notification to the user with that email. The user now has the option to accept or deny the request. Choosing any of those actions would update the notification document which will again invoke a cloud function that would add both users to each other's friends list and notify the first user.
So my questions are: -
Is this method reasonably good to be implemented in a production app since it is involving many cloud function invocations and document read and writes? Or even better question - How would you implement something like this in a production-grade app?
Is there any other method that is secure (in the sense that no one should be able to wreck this process by changing the code on the frontend) and efficient (less read/writes/invocations)?
Can this be done without creating any document whatsoever? Purely by cloud functions? Then would it be able to capture other user's response to friend request and do the necessary changes?
For the problem you are describing I would approach it in the say way you are doing, and in fact there are not that many operations going on here, since you would have 2 Firestore writes and 2 invocations of cloud functions, not to mention that the second invocation could take a long time to be fired depending on the user's actions, so you don't need to be more efficient than that.
To you final question I would say that it would be difficult to have this implemented without information going through Firestore because you need to store the acceptance of the friend request, and for the same reason mentioned above, you need to store that information somewhere, even if temporarily.
I know I'm late but maybe this will help to someone else.
My way adding sent - receive friend request system is following:
For example:
me:
{
name:'John',
id:'20'
};
stranger:
{
name:'Lucas',
id:'50'
}
When I click add friend (on stranger) I will call function:
addDoc(doc('users', stranger.id, 'receivedFriendRequests'), { user:me });
This function will add ME into his receivedFriendRequests docs so he will be able to get that docs and check users who sent request to him.
So, in notifications Component you have to just get your receivedFriendRequests` docs and map all users and make function to accept friend requests for each of them.
When you click accept you need to delete that user from receivedFriendRequests and store both users in "friends" collection. You can do it in your own way, but I give the best example, in my opinion.

How to sync IndexedDB with Firestore?

I am building a job portal for the web using React, Redux and Firebase/Firestore. I've completed all the features I needed except one.
I want unregistered-users/job-seekers to be able to:
Bookmark job posts.
Keep the record of applied jobs.
Keep the record of search queries.
I am thinking about using IndexedDB for this feature. Particularly Dexie.js to make things easier. However, this data will be persisted in user's browser and user will have no access to it in another browser or device. Therefore, I want to give users an option to be able to save all the data to Firestore if user sign into the website and I need this to be automatic. So, as soon as user signs in, I will save it to the database.
I thought about using Anonymous Authentication instead of IndexedDB/Firestore, so all the data will be saved into the database and as soon as user signs in using credentials, the user can claim the ownership of the data. However, this is an extra step to use these features I listed above and not everyone is happy with authenticating an app even though nothing is required from the user. Besides, there will be so many ghost accounts.
So, as I mentioned in the title; I want to save everything to IndexedDB (I will take care of this), but how am I going to synchronize all the data in IndexedDB to Firestore as soon as user signs in?
I imagined the basic process will be like this:
User clicks "Bookmark Job Post"
App checks if users is authenticated or not.
If authenticated, save the bookmark to the Firestore.
If not authenticated, save the bookmark to the IndexedDB.
If User decided to sign in or sign up, check IndexedDB and synchronize it with Firestore and clear IndexedDB.
How can I achieve the 5th step technically? Is there any built in system in Firebase? Also, please feel free to share your idea if you can think of another way implementing this feature. Should I be using firebase.auth().onAuthStateChanged() for the 5th step?
And lastly, how should I structure the Firestore to save bookmarked jobs, applied jobs and search history?
Should I create a bookmarkedJobs collection and have documents of jobPosts duplicated for each user, who bookmarked the job post? And every time a job post is updated by an employer, I will have a cloud function going through bookmarkedJobs collection, updating every instance of it?
Thank you
This may be of interest to you
https://dexie.org/docs/Syncable/Dexie.Syncable.js
Been looking into making my website fully static/pwa, and just using indexeddb, and some webservice for data handling/storage ..this seems like a interesting route to explore.

Do we really need Vuex when building a web app using Firebase + Vue?

We are building a to-go order web application for restaurants with Firebase and Vue.
Restaurants can create their own pages, and add menu items.
Users (customers) can orders some foods from those restaurants pages, and pick them up later.
At the beginning of the project, we have chosen to store some transient data (user data, shopping carts, etc.) in the Vuex store. It works fine but there are a lot of complexities in it, which made it hard to maintain.
Recently, I have realized that we could just use Firestore for those transient data as well, which will greatly simplify the architecture, eliminating Vuex completely.
Before making all the changes, I want to make it sure that I am on the right track and I am not missing anything.
I'd really appreciate any comments and suggestions from those people who have experience in building relatively large scale web applications using Firebase + Vue (or even React).
Short Answer
Yes, this seems perfectly reasonable.
Long Answer
Many web applications have their state synchronized via an external service like Firebase, GraphQL, etc. In these cases you may already be using some kind of shared, UI-independent cache (e.g. Frestore, Apollo client). Unless the aforementioned cache cannot be easily accessed by your UI components, there would be little benefit to switching or duplicating the data to Vuex.
Keep in mind that even in the above scenario, Vuex can still be a useful tool to track UI-specific state across otherwise disconnected components in your interface. For example, you could globally identify the user's current viewing mode, or which modal is open.
Yes you can go without VUEX, however, it will limit your potential.
First of all vuex is really simple, you can easly add vuex your code.
Without Vuex you may write same code again and again.
For example you want to redirect your user to his restaurant page when he logs in. So you write a code that first checks if user has a restaurant and then gets his restaurant ids.
Also you want to check when a user opens a restaurant page, if the user owns that page, you write the same code again. However, if you have a function that returns a value if user is the owner or not. You can call it any page you want.

Get origin for newly created user on firebase auth trigger

Is there a way to know if a newly created user was done so using the client or admin SDK?
No, the auth trigger isn't origin specific. It doesn't care how a new user account gets created... it doesn't get called/triggered until the creation occurs.
Not to go too far off topic from your question, or turn this into a fully-fledged conversation, but what are you trying to accomplish that you want to detect what created the account? I feel like there's probably a different way to handle the scenario you're facing.

Resources