invalid Firebase binding source when trying to use readyCallback with vuefire - firebase

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

Using react-papaparse in the Next.js getStaticProps - XMLHttpRequest is not defined

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)
},
});
}

How do I read session properties using useSession() in getServerSideProps() using nextjs and next-auth?

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).

Can anyone help implementing Nuxt.js Google Tag Manager with function based id

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']
}

With vuejs, how do I get firebase (vuefire) object into component data

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.

Vuejs & Firestore - How to Update when Data Changes in Firestore

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!

Resources