This might be a stupid question but I am learning all of this by myself and I didn't find anything about it in the documentation.
I am currently building a Vue app and using Firebase as my backend. In order to use the Firebase services, you create an app object with the initializeApp() method and then access services like the database by calling getDatabase(app) and working with the returned object. Now my question is: If I do these things inside my top level component (App), but then need to access the database inside another component, can I just call the getDatabase() method again, or do I have to somehow export the first object so that I can access it from other files?
The Firebase SDKs are pretty good at re-using objects behind the scenes, so you can typically call initializeApp once and then call getDatabase in each component.
Related
I'm starting to learn about vuex. I have the question should I set this data from the Store or should I load it on the component?
For example, In my app, I load all users (firebase) from a Store Action and read it from the Getters, but when it comes to load one user data, should I fetch it from the state and then to the component or from the component itself?
I just want to make sure to make my life easier when updating or adding a new feature on the app.
Your store should be your only source of truth for global state.
This means that any component that read data should read from the store. This ensures consistency. Of course each component may need some local data, that it gets using other means and can alter the data that it gets from the store, but it should read from there.
Now you only have a dilemma regarding who should write to the store (using mutations and actions). This depends heavily on your use cases. It is perfectly acceptable to write from the components itself.
There are use cases where populating some data from outside any component makes sense. Probably the most common case is auth credentials. It is easier and cleaner to populate auth credentials before mounting the app for instance so you have one choke point for dealing with authed/unauthed users.
Bottom line is, writing to the store depends on your use case and there's no silver bullet here.
When using Firestore, I see people using this pattern:
export const db = firebase.firestore();
And then use the db reference across the app to access the Firestore interface.
But I don't usually do this. I prefer to use it like:
firebase.firestore().collection("myCollection").get() // I USE IT LIKE THIS ACROSS THE APP
Whenever I need Firestore, I always call firebase.firestore()
Basically I'm getting the same reference over and over again to the Cloud Firestore service interface.
And it works just fine.
QUESTION
Can the same concept be applied to the firebase.analytics() call?
I.e: can I call it multiple times throughout my app (like the Firestore example) or will I be logging the same default events over and over again on each call?
Like: calling firebase.analytics() everytime I need the Analytics interface.
Because I know that just by calling it once, you're already logging (sending) out some default events.
Would it make any difference to use it like this:
export const analytics = firebase.analytics();
And then use the analytics to log events, instead of firebase.analytics().logEvent() everytime ?
firebase.analytics() just returns a singleton object, the same every time. All of the Firebase product entrypoints exposed by the firebase object are all that way. Whatever method you want to use to get that singleton object is completely up to you.
I have created several components (tables, selects, etc) and all use the same methods to get API information.
The purpose is to use these components on different pages of the application and as such, so that one can use the same component (eg table) regardless of the information it receives, I have created a number of methods to allow this.
However, to apply these methods to all components requesting the API, you would have to repeat a lot of code, and as such the goal is to create these methods globally.
After a search I found three ways to do it, with Plugins, Mixins and Vuex. However I do not know what is the most ideal way to do this.
Any suggestion?
Go with Vuex.
Create a centralized store where your components interact with its data using getters, actions and mutations, and the store knows how to interact with the API.
For example, your table component can be dumb, and just expect a :data=someData that the component that initializes the table passes to it, then it just renders whatever was passed. This someData can be mapped to a Vuex getter (or directly to an item in the store state) in the parent component.
When your component needs to have something submitted to the API, it can trigger an event the parent will pick up and call the appropriate action or mutation on the store, the store will know what to call in the API to do this action. So, even your parent isn't completely aware on how the API works, just your abstraction of if, represented by your Vuex store.
I have created a very simple todos application last week for another question here, feel free to have a look, uses Vue, Vuex and saves the data to Firebase. It also doesn't implement REST as it could, but it isn't too hard to change the store to use the proper REST methods get, post, put, delete etc.
All the relevant code of this application in in App.vue and store.js, with one line in main.js just to add the store to the Vue instance.
Vuex will help with shared/own components state. If your problem is how to manage shared API call Vuex persi won't tackle that problem directly. It will help you once you get that data accessible to your components.
That said, you can create a module to do the API call and retrieve data, say:
http.js
export const getUser = async id => {
const response = await fetch(`/user/${id}`)
return await response.json()
}
export const getContent = async id => {
const response = await fetch(`/content/${id}`)
return await response.json()
}
This is a solution that will help you both with or without Vuex, now you can call those methods from anywhere.
I have problem with sharing objects that were created within some component. I am curious how can i access those objects in another component. Can i create a global variable that is accessible within all classes? Unfortunately, i cannot find any relative answers or project in the web.
Create a closure within the component that will hold all the data you want to make available to other components, then export it alongside your component.
whenever you want to use that shared data, require the closure the same way you require a component.
ps: probably it's better to use any variant of Flux, I recommend Redux
Well if you wanna give a children some of the parent object you can do
in the parent:
<Children anything={yourObject} />
and access to yourObject in the children using:
const childrenObject = this.props.anything
But this will work in a simple react app, If you are planning to do something more complicated then you should try to learn redux, it will give your app a global state called Store where you will put whatever you want and access anywhere in your app
https://www.codementor.io/mz026/getting-started-with-react-redux-an-intro-8r6kurcxf
I have file which exports various utility functions to use across components, and these functions needs to access redux state. How do I import the state object to this file?
connect does not work here if your utility functions are not react elements.
Best idea is, import create store and then use getState function,
import store from 'store/createStore';
const state = store.getState();
Well, this isn't a simple answer, but after researching this for too long, I found these, which are the only 2 articles that explain anything. They explain how to access the store directly outside of a Component (if you must) and also mention the pure functions / functional programming philosophy as well as potential performance issues with connecting a bunch of non-component functions to the store directly. Personally, I went with #anoop and passed the params around in a single object as deeply as needed.
For connecting directly (which gets the store from this.context the way connect() does, see the discussion here
and specifically gaearon's comment on Sep 16, 2015 and Sep 22, 2015.
It seems this access can be achieved via connect()
For a little reading on functional programming / pure functions, see the discussion here
The utility should get the state as an argument.
Because you want to use the utility in the components (views) you can store the state in a member variable on your smart component (the one using connect() function) via mapStateToProps(state) callback.
then you can pass this member to your dumb components.