Firebase Packages called within Custom Packages - javascript

I'm working on custom packages we use internally in our organization and I'm trying to reduce how many properties I need to pass into the Component I'm creating for the package. One of the components I'm building involve firebase/storage. I want to only pass the result of getStorage() from my app and let the package import ref, uploadBytes, etc. I don't want to have to import them individually and pass them as props. However, whenever I try to import ref in the package and call ref(storage), it returns the FirebaseStorageImpl again, not the StorageReference I expect.
Some code from the compiled package:
import React, { useState, useEffect } from 'react';
import { ref, uploadBytes, deleteObject } from 'firebase/storage';
export const Files = (props) => {
const {
storage
} = props;
console.log(
storage,
ref(storage)
);
}
And my application file:
import { React } from 'react';
import { Files } from 'my-package';
import { initializeApp } from 'firebase/app';
import { getStorage } from 'firebase/storage';
const App = () => {
const firebaseApp = initializeApp(/* FIREBASE CONFIG */);
const storage = getStorage(firebaseApp);
return (<Files
storage={storage}
/>)
}

Related

Vue3 - Setting up Pinia gives me an error of no active Pinia

I have this Vue app I would like to convert the store to a Pinia store because the normal reactive store just doesn't work and does not keep the values I set.
So I installed pinia and I have the following main.js file:
import { createApp, h } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";
import router from "./router";
import { store } from "./store";
import axios from "axios";
axios.defaults.baseURL = "http://127.0.0.1:8000";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
axios.defaults.xsrfCookieName = "csrftoken";
const pinia = createPinia();
const app = createApp(App).use(router, axios, store, pinia).mount("#app");
I have created a store inside a stores folder and here is that store:
import { defineStore } from "pinia";
export const useSomeAppStore = defineStore("someapp", () => {
const userID = ref(0);
const loggedIn = ref(false);
});
On the log in page I would like to use this store so I can save the user id in the store.
<script setup>
document.title = "Login | addapost";
import axios from "axios";
import { ref, watch, onBeforeMount, onMounted } from "vue";
import { useSomeAppStore } from "#/stores/someapp";
import { useRouter, useRoute } from "vue-router";
const store = useAddapostStore();
</script>
If I refresh the log in page I see the following error in the console:
Uncaught (in promise) Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
const pinia = createPinia()
app.use(pinia)
This will fail in production.
Why is this error happening and what am I doing wrong here please?
The problem is with axios I don't have to use(axios) in the main.js file. Wonder why some people add it to the main.js file and it works but for me it doesn't.
But now I have another problem. I got pinia working and it says the store is installed and I see the user id when I am logged in. As soon as I refresh the data is lost and the user id becomes 0. Why is the store not keeping my data?
You can’t pass multiple plugins to a single app.use() method.
Instead, you have to chain them - one plugin each:
app.use(…).use(…)

React Loadable and Meteor separate bundle

I am using the following Component with Meteor
https://github.com/CaptainN/npdev-react-loadable
import { Loadable } from 'meteor/npdev:react-loadable';
I create my Loadable component as follows
const HomePageBlog = Loadable({
loading: () => <FullPageLoader />,
loader: () => import('./HomePageBlog'),
});
I have gone through the SSR setup in the docs and it looks something like this
Server index.js
import React from 'react';
import { renderToString, renderToNodeStream } from 'react-dom/server';
import { onPageLoad } from 'meteor/server-render';
import { StaticRouter } from 'react-router';
import { Helmet } from 'react-helmet';
import Loadable from 'react-loadable';
import { ServerStyleSheet } from 'styled-components';
import {
LoadableCaptureProvider,
preloadAllLoadables,
} from 'meteor/npdev:react-loadable';
preloadAllLoadables().then(() => {
onPageLoad(async (sink) => {
const context = {};
const sheet = new ServerStyleSheet();
const loadableHandle = {};
const routes = (await import('../both/routes.js')).default;
const App = (props) => (
<StaticRouter location={props.location} context={context}>
{routes}
</StaticRouter>
);
const modules = [];
// const html = renderToNodeStream((
const html = renderToString(
<LoadableCaptureProvider handle={loadableHandle}>
<App location={sink.request.url} />
</LoadableCaptureProvider>,
);
// we have a list of modules here, hopefully Meteor will allow to add them to bundle
// console.log(modules);
sink.renderIntoElementById('app', html);
sink.appendToBody(loadableHandle.toScriptTag());
const helmet = Helmet.renderStatic();
// console.log(helmet);
sink.appendToHead(helmet.meta.toString());
sink.appendToHead(helmet.title.toString());
sink.appendToHead(helmet.link.toString());
sink.appendToHead(sheet.getStyleTags());
});
});
client index.js
import { Meteor } from 'meteor/meteor';
import React from 'react';
import ReactDOM from 'react-dom';
import { Router, withRouter } from 'react-router-dom';
import { onPageLoad } from 'meteor/server-render';
import { createBrowserHistory } from 'history';
import { preloadLoadables } from 'meteor/npdev:react-loadable';
console.log('hi');
const history = createBrowserHistory();
/**
* If browser back button was used, flush cache
* This ensures that user will always see an accurate, up-to-date view based on their state
* https://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked
*/
(function () {
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
})();
onPageLoad(async () => {
const routes = (await import('../both/routes.js')).default;
const App = () => (
<>
<Router history={history}>
<div>{routes}</div>
</Router>
</>
);
preloadLoadables().then(() => {
ReactDOM.hydrate(<App />, document.getElementById('app'));
});
});
What I am trying to determine is what exactly react loadable does. I am wanting to separate my bundle so I can only load code via SSR when it is needed. Right now I have quite a low score on lighthouse for page speed.
The code that I have here works.
But what I expected to happen was have a separate request to grab more js for the loadable component when it is requested. So it's not in the initial bundle. Is this not how this package works.
Could someone one help me me understand this better.
Thanks for any help ahead of time

React Native: use mobx store state from another store

I was wondering how can I use a n observable from one store inside another store class, for example use userStore inside mapStore.
Now I will show you how I initiate stores and use them in my functional components:
/contexts/index.js
import React from 'react'
import { configure } from 'mobx';
import { UserStore } from '../stores/UserStore.js'
import { MapStore } from '../stores/MapStore.js'
export const storesContext = React.createContext({
userStore: new UserStore(),
mapStore: new MapStore(),
});
configure({ enforceActions: "observed" });
/hooks/use-stores.js
//hooks/use-stores.js
import React from 'react'
import { storesContext } from '../contexts/index.js'
export const useStores = () => React.useContext(storesContext);
Inside my functional components I access like this:
import { useStores } from '#hooks/use-stores';
...
const { mapStore,userStore } = useStores();
An example class, UserStore
export class UserStore
{
constructor()
{
makeAutoObservable(this);
user = false;
}

React Native: firestore/firebase Expected first argument to collection() to be a CollectionReference... how?

So I have a simple React Native app that I created using Expo and debug on my personal Android device.
I've included firebase/firestore into my app and am now trying to add an object to firestore on button click.
Here's my code:
firebaseConfig.js :
import { initializeApp } from '#firebase/app';
var config = {
...
}
const app = initializeApp(config);
export default app;
Component:
import { app } from '../firebaseConfig';
import { getFirestore } from 'firebase/firestore/lite';
import { doc, setDoc, collection, query, where, getDocs, initializeFirestore } from "firebase/firestore";
...
export default function Component() {
const firestoreDb = getFirestore(app);
// this function is called when clicking a button
const onAddListPress = () => {
setDoc(doc(firestoreDb, "cities", "LA"), {
name: "Los Angeles",
state: "CA",
country: "USA"
});
}
}
This throws the following error:
Expected first argument to collection() to be a CollectionReference, a DocumentReference or FirebaseFirestore
This code above (in the onPress) is copied from the official firestore docs, here:
https://firebase.google.com/docs/firestore/manage-data/add-data#set_a_document
Does anyone have an idea why this does not work?
I suggest you edit your post and remove the firebaseConfig configuration keys, or delete your Firebase app and create a new one from the Firebase console to secure your app. I tried to replicate your application using React, and I received the same error message. There were two changes I made to correct the error. The first one is inside the firebaseConfig file, the default export needs to be changed to a named export:
import { initializeApp } from "firebase/app"
const firebaseConfig = {
//Project configuration keys
};
const app = initializeApp(firebaseConfig);
export { app }; // Change from a default to a named export
In addition, all the imports inside your component should come from the full Javascript SDK, not the lite version. The lite version has some limitations which can result in this specific error.
import { app } from "./firestore-config";
import { getFirestore, getDoc, doc } from "firebase/firestore";
import './App.css';
export default function App() {
const firestoreDB = getFirestore(app);
const docRef = doc(firestoreDB, "users", "testUser1");
const getData = async () => {
const data = await getDoc(docRef);
console.log(data);
}
getData();
return <div className="App"></div>;
}
You might also want to review this GitHub issue if you are using yarn to manage your dependencies.

#react-native-firebase integration with react-redux-firebase V3

Does anyone know how to integrate #react-native-firebase with react-redux-firebase V3 ?
I have installed react-native-firebase following this tutorial https://rnfirebase.io/
"dependencies": {
...
"#react-native-firebase/app": "^12.1.0",
"#react-native-firebase/auth": "^12.1.0",
"#react-native-firebase/firestore": "^12.1.0",
...
},
The git code how to implement react-redux-firebase with react-native seems to be deprecated as it still using the V2
The documentation on the website :
use firebase without importation when configuring the store ?
use import from 'react-redux-firebase' and not '#react-redux-firebase/...' (what is the difference ?)
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
import RNFirebase from 'react-native-firebase';
import { createStore, combineReducers, compose } from 'redux'
import { ReactReduxFirebaseProvider, firebaseReducer } from 'react-redux-firebase'
// import { createFirestoreInstance, firestoreReducer } from 'redux-firestore' // <- needed if using firestore
...
// Initialize firebase instance
firebase.initializeApp(fbConfig)
Does anyone know how to integrate correctly #react-native-firebase with react-redux-firebase V3 ?
Here is the solution,
You will need to import modules like this
and also retrieve an instance of firebase with the app() function.
Here is my configStore file
import {createStore, applyMiddleware, compose} from 'redux';
import rootReducer from '../Redux/Reducers/rootReducer';
import middlewares from '../Redux/Middleware/middleware';
import {createFirestoreInstance} from 'redux-firestore'; // <- needed if using firestore
import {persistReducer, persistStore} from 'redux-persist';
import rrfConfig from '../Redux/Config/reactReduxFirebaseConfig';
import persistConfig from '../Redux/Config/persistConfig';
// Cherry-pick modules of react-native-firebase 6.x
// import '#react-native-firebase/analytics';
// import '#react-native-firebase/crashlytics';
// import '#react-native-firebase/dynamic-links';
// import '#react-native-firebase/perf';
// import '#react-native-firebase/remote-config';
import '#react-native-firebase/auth';
import '#react-native-firebase/firestore';
import '#react-native-firebase/database';
import '#react-native-firebase/storage';
import RNfirebase from '#react-native-firebase/app';
const firebase = RNfirebase.app(); // <-- Retrieve an instance of a FirebaseApp.
// persist reducer in storage
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Create store with reducers
const store = createStore(
persistedReducer,
compose(applyMiddleware(...middlewares)),
);
// react-redux-firebase props
export const rrfProps = {
firebase,
config: rrfConfig,
dispatch: store.dispatch,
createFirestoreInstance, // <- needed if using firestore
};
export const persistor = persistStore(store);
export default store;

Categories