This is my first time using Vuefire. I want to render some data after the data is loaded using db.ref('page_data'). In the docs, I have read that you can use a function inside of firebase: {} to have a callback when its ready called readyCallback: function(){}
but for some weird reason when I use this firebase throws an error:
invalid Firebase binding source
My <script> tag looks like this
import { db } from "./firebase"
export default {
name: 'App',
firebase: {
data: db.ref('page_data'),
readyCallback: function(){
console.log("Ready!")
}
},
data(){
return{
data: ui_data,
}
}
}
If i remove readyCallback no errors are shown, but the problem is that if i try to render the data before the request is finished the vue app errors out on me.
readyCallback should be nested inside:
firebase: {
data: {
source: db.ref('page_data'),
readyCallback: function(){
console.log("Ready!")
}
}
},
Related
I am trying to use papaparse inside my Next.js page. I am using react-papaparse package which is a React wrapper for Papaparse. I am trying to parse remote CSV file inside getStaticProps() function but the error I get is XMLHttpRequest is not defined.
I know that getStaticProps() is executed on Node.js but I don't know how to use react-paparse correctly to avoid XMLHttpRequest call. Here is my code:
// index.js Next.js page
import { usePapaParse } from "react-papaparse";
export async function getStaticProps(context) {
const { readRemoteFile } = usePapaParse();
readRemoteFile(googleSheetUrl, {
complete: (results) => {
console.log("PAPAPARSE::complete", results)
},
});
}
I am trying to only show data where the "Heading" is the same as the logged-in user's name. I'm using Next.js and I'm trying to server render the data from my Prisma database, but when I try to filter the data to only show "Segments" where the "Heading" is the same as the currently logged-in user it throws an error:
Server Error
TypeError: Cannot read properties of null (reading 'useContext')
I am using Next-Auth for user authentication and previously I have use this method to access the currently logged in user's data:
import { useSession } from "next-auth/react";
.
.
.
const { data: session } = useSession();
.
.
.
<div>User name: {session.user.name}</div>
But when I use getServerSideProps() that method doesn't work.
This is what I tried so far:
export async function getServerSideProps() {
const { data: session } = useSession();
const segments: Segment[] = await prisma.segment.findMany({
where: {
Heading: session.user.name,
},
});
return {
props: {
initialSegments: segments,
},
};
}
But it shows me the error shown above.
useSession is unavailable on the server side according to next-auth's docs.
You may be able to use unstable_getServerSession(), however do note that it's experimental and its API may change in the future (as noted in the docs).
I installed and add this code to my nuxt.config.js and it works perfectly fine. (Link to package)
modules: [
['#nuxtjs/google-tag-manager', { id: 'GTM-XXXXXXX' }],
]
Now I am trying to implement instead of a static ID a function which will return an ID.
I tried to add this lines into my nuxt.config. js but it is not working. Obviously I have to put it somewhere else or so...
This is what I tried
nuxt.config.js
const code = '1234567'
id: () => {
return 'GTM-' + code
}
export default {
...
modules: [
['#nuxtjs/google-tag-manager', { id: id }],
]
...
}
What would be the correct way implementing this?
I would like to do something like that at the end.
modules: [
['#nuxtjs/google-tag-manager', {
id: ({ req }) => {
if (req.headers.referer == "exmple.com")
return 'GTM-156'
if (req.headers.referer == "exmple.it")
return 'GTM-24424'
if (req.headers.referer == "exmple.es")
return 'GTM-2424'
}
}]]
EDIT:
I solved my problem by rewriting the whole module. It is not possible to use this Module because it is loaded only on build time. I rewrote the module and moved the code into nuxtServerInit.
nuxtServerInit is called on each request (modules only onetime). In the request I asked from which domain the request is coming. Depending on the domain I add different google-tag-manager id's to the head and the plugin.
From package docs:
modules: [
['#nuxtjs/google-tag-manager', {
id: () => {
return axios.get('http://example.com/')
.then(({ data }) => {
return data.gtm_id
})
}
}]]
You can use process.env.NODE_ENV inside function which will return an ID
Edit 1
To put the gtm id, depending on req.headers.referer you need to provide context to the function returning the id. This can be done in middleware
See how it works here
https://github.com/nuxt-community/modules/blob/master/packages/google-tag-manager/plugin.js
Edit 2
As far as I understand your question, it will not work to have a query context in the config.
Look at i18n middleware: request.locale - > store - > update modules (router, vuetify, moment, etc.)
https://nuxtjs.org/examples/i18n/
~/middleware/gtm.js
export default function ({ app, store }) {
// app.$gtm contains id, you can set another from store
}
don't forget to add middleware to the page
page.vue
export default {
middleware: ['gtm']
}
Using firebase 4.10.1 and vuefire 1.4.5.
I have confirmed that I have initialized firebase, exported a db const, and imported vuefire correctly.
I am trying to load my firebase object (JSON) onto my dataTable component data.
I am trying this:
export default {
firebase: function () {
return {
fbObj: db.ref('collection')
}
},
data () {
return {
dataTable: fbObj
}
}
}
It's wired up correctly because if I use {{ fbObj }} in my template I get the JSON object displayed in full. However, if I try to load it onto the dataTable I get "fbObj is not defined" as console error.
How can I load my firebase object onto the dataTable?
The code:
firebase: function () {
return {
fbObj: db.ref('collection')
}
},
Creates a this.fbObj available to your Vue instance. So instead of dataTable: fbObj the correct would be more like:
data () {
return {
dataTable: this.fbObj // but even this won't work
}
}
But that won't work. You can't do it because that data() initialization code will be executed before the fbObj has been initialized (it takes a bit of time to update it from firebase).
So if you want dataTable to refer to that collection, either:
Rename the firebase object to dataTable:
firebase: function () {
return {
dataTable: db.ref('collection')
}
},
Or create a computed property:
firebase: function () {
return {
fbObj: db.ref('collection')
}
},
computed: {
dataTable() {
return this.fbObj;
}
}
Then you can use this.dataTable in the Vue instance JavaScript or dataTable in the template.
I've gone through a bunch of tutorials and docs but cannot seem to be able to update on page when data changes in Firestore (NOTE: not Firebase)
Heres what I have currently which is working fine except if data changes in the DB it is not reflected on the page itself unless I refresh. Code below is within script tags:
import { recipeRef } from '../../firebase';
export default {
data() {
return {
recipes: []
}
},
firestore: {
recipes: recipeRef
},
created() {
db.collection('recipes').get().then((onSnapshot) => {
this.loading = false
onSnapshot.forEach((doc) => {
let data = {
'id': doc.id,
'name': doc.data().name
}
this.recipes.push(data)
})
})
}
I'm not using Vuex. Adding data, editing and reading works fine. Just not reflecting changes once data has changed. Maybe there is a life cycle hook Im supposed to be using? For "onSnapshot" - Ive tried "snap", "querySnapshot" etc. No luck.
Thanks in advance.
Remove the get() and just replace with snapshot - like so
created() {
db.collection('recipes').onSnapshot(snap => {
let foo = [];
snap.forEach(doc => {
foo.push({id: doc.id, name: doc.data().name})
});
}
});
I am not familiar with the firestore API, but glancing through the docs, it looks like calling get() is how you query a single time. Where you have onSnapshot should really be querySnapshot -- that is, the results of a one query. See:
https://firebase.google.com/docs/firestore/query-data/get-data
versus:
https://firebase.google.com/docs/firestore/query-data/listen
So to get live updates, it looks like you need to create a listener, like so:
db.collection('recipes')
.onSnapshot(function(snapshot) {
snapshot.forEach(function(doc) {
// Find existing recipe in this.recipes
// and swap in the new data
});
}, function(error) {
// handle errors
});
I think you will need to add that listener in addition to the get() query you are currently doing. Hope this helps!