So let's say I initialized my app like this
const firebaseApp = firebase.initializeApp(firebaseConfig)
And say I want to get an instance of the firestore database
const db = firebaseApp.firestore()
What is the difference between that, and this:
const db = firebase.firestore()
I think it will just give me a new instance, is that right?
If it is a new instance, what is the difference between the first one?
Also if you want to configure the setting of the firestore instance, is it better to do it like this:
db.settings(options)
Or
firebase.firestore().settings(options)
No difference. When you call initializeApp(), if you don't pass a second parameter giving the app a name, it will work with the default app and return that App instance. That's the same default app that's used when you call firebase.firestore().
If you ever want to work with a different app instance, you will have to refer to it by name.
Related
I'm using react-admin. I have firebase.js, which exports a data provider and an auth provider. Right now firebase.js looks something like
export const authProvider = MyCustomAuthProvider(...)
export const dataProvider = FirebaseDataProvider(..., {rootRef: "users/[authProvider.get~this~user().email]")
But I'd like the dataProvider imported to change when the user logs in / out (the reason being that the data provider has as its root collection at 'users/[user email]'). That's actually why I stopped using the FirebaseAuthProvider blackbox, because I figured I could use the login/logout functions to trigger changing the dataProvider.
What's the best way to accomplish this? Just declare the dataProvider using
let dataProvider = null and every time a user logs in/out, set that variable. And then add a function to the auth provider that returns that variable? There seems to be a more elegant way, but I'm not as experienced in JavaScript unfortunately.
Also for reference, the reason I'm taking this approach instead of just creating a dataProvider with rootRef 'users' and then accessing the correct collection / document when I want to view or modify data is because FirebaseDataProvider is a bit of black box and doesn't allow me to do that (unless I'm missing something). If I could get this all to work with FirebaseDataProvider, it has saved me a ton of time so that would be great.
Problem
I want to have a global counter in react native to show how many notifications a user has in an app that I am creating.
I created a global variabal in a file named global.js:
var notifNum = 0;
global.n = notifNum;
then in my code, I import it with
import './global.js'
then later I try to update it with
global.n = notifNum;
Notif num being the number of notifications a user has, defined in a function. The problem is that global.n stays as 0, and doesn't change at all.
How can I edit the global.n variable?
There is one hacky way to modify a global.foo variable.
Dosnt work
global.foo = 'foo'; //this cant be changed
global.foo = 'foofoo';
console.log(global.foo); //foo
Does work
global.foo = ['foo']; //this can be changed
global.foo[0] = 'foofoo';
console.log(global.foo[0]); //foofoo
This has less to do with React-Native and more to do with how javascript works as a language.
In short, you must export what you wish to use in other files.
Global.js
let counter = 0;
const increment = () => {
counter++;
console.log('counter_updated', counter);
};
const worker = {
increment,
counter
};
module.exports = worker;
We've told the JS engine exactly what we want to import in other files. Assigning it to and object and exporting the object is not necessary but allows for cleaner imports/exports IMO.
Component.js
import { counter, increment } from 'pathTo/global';
We deconstruct the object we exported and are now able to modify/use values in the global.js file.
Food for thought
This is not an ideal solution as it is not two ways. Incrementing the count in the global.js file will not update the value in the component.js.
This is because React needs to have it's state updated to initiate a re-render of a component.
Also, this will not persist through app reloads, which I believe you would want for something such as notifications.
Other solutions
Storing the notification counts in a database.
Using component state to manage the count.
Using a state manager like Redux or MobX
I'm trying to implement an external API library in a redux application.
I'm fresh new in redux so I don't know exactly how it works.
In my javascript using the API library, I wan't to access info from a container (the user firstanme if he's logged).
After reading some doc, I tried to import the store in my js file, to get the state of the user, but I can't reach the info I need.
Here's the code I tried :
import configureStore from '../store/configureStore';
const store = configureStore();
const state = store.getState();
I get many info in state, but not the one I need. Any help ?
First of all it looks like configureStore creates new store every time you call it. But you need the very that store that your components will use and populate. So you need to somehow access the store you are passing your Provider.
Then since store state is "changing" you can't simply read it once. So your user data might be initially empty but available some time later.
In this case you could make it a Promise
const once = selector => available => new Promise(resolve => {
store.subscribe(() => {
const value = selector(value)
if(available(value)) resolve(value)
})
})
And usage
const user = once(state => state.user)(user => user && user.fullName)
user.then(user => console.log(`User name is ${user.fullName}`)
Or if your data might be changing more than once during application lifecycle you might want to wrap it with something that represent changing data (observable). RX examle
I'm primarily a C# developer with limited experience in JavaScript/EcmaScript and trying to understand the right way to create an instance of an API service that I can reuse in my functions.
The app I'm working on is a React app and the API service I'm trying to consume is Google Places. I created an external file for all Google Places related functions so that they're reusable. Here's the function I have in that file that will make the API call to get some suggestions from Google.
export const googleCall = (keyword) => {
const googlePlacesAutocomplete = new google.maps.places.AutocompleteService();
googlePlacesAutocomplete.getQueryPredictions({input: keyword}, callback);
}
It makes no sense to keep "new"ing google.maps.places.AutocompleteService() every time a new keystroke comes into this function.
One option I can think of is that in my React app -- say in ComponentWillMount --- I can create an instance of this service and then pass it into this function along with the keyword but that seems a bit cumbersome. That would look something like this:
export const googleCall = (googleService, keyword) => {
googleService.getQueryPredictions({input: keyword}, callback);
}
I think a better way would be to make sure the googleCall() function can access what's in the state i.e. in my redux store. In other words, I could create an instance of the googleService in a ComponentWillMount function and place it in my redux store. Just not sure how I can have this function access what's in my state.
Or, more generally speaking, in ES -- in particular in ES2015 -- how do I create an instance of this service that my googleCall function can access every time I call it without having to create a new instance of the service? I'm just not sure how this is done in ES where we create an instance of something and keep it in memory for subsequent calls.
UPDATE:
In my React component, I simply get the googleCall function like this:
import {googleCall} from '../googlePlacesFunctions';
I'm somewhat confused by your question. Why not just?
// api.js
const googlePlacesAutocomplete = new google.maps.places.AutocompleteService();
export const googleCall = (keyword, callback) => {
googlePlacesAutocomplete.getQueryPredictions({input: keyword}, callback);
}
That way you're not passing things around anywhere and you're not creating more than one instance of AutocompleteService
I've used higher order component to share a function between my components.With this implementation,the function comes as a prop in my component.The app supports multi languages so in each component a key is passed and the hash value is obtained to display. Hash values are passed to all the components using the context. Now getSkinHash access the context and returns the hash value.
const {getSkinHash} = this.props; //shared function,accesses the context
const value = getSkinHash(SOME_VALUE);
No problem with this implementation but getting the function out of prop every time leads to writing lot's of boilerplate code in all the components.
Is there a better/alternate ways to achieve this?
Thanks
React works with properties, so you can't just say you don't want to work with properties. That is when sharing data between components.
As far as you can do to shorten
const {getSkinHash} = this.props;
const value = getSkinHash(SOME_VALUE);
is to:
this.props.getSkinHash(SOME_VALUE).
If that is a generic function, not component dependent, you can choose to import it into your component just like you import other stuff.
import { myFunction } from './functions'
Then you would simple call it with myFunction.
If you need your function to synchronize data between your components, use a Redux action and connect your components to the global state. Your other components will get to know value hash changes too.