something weird is going on. I am using Vue.js and Firebase. my query is simple. I have 3 documents in the database
let tagRef = db.collection('tags')
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.onSnapshot(snapshot => {
this.tags = []
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.tags.push(docs.data())
console.log(this.tags.length)
})
})
as you can see I am logging the array length to the console. when I refresh the page my console log reads 1 1 2 however when a change is made is reads correctly 1 2 3
I am not sure why it is doing this.
When I change the console.log from this.tags.length to this.tags attached are the screen shots of what I get.
on page refresh
when a change occurs
any help is greatly appreciated.
UPDATE:
This is a game. players can tag each other. when a player gets tagged they are disabled temporarily until their tag is complete. the second piece is each player can be tagged no more than 3 times.
In the created() hook I query for the tags and I am using the realtime part of firebase so anytime something changes with the tag database the code is updated.
I have a method as seen below:
countTags(team) {
return this.tags.filter(function (tag) {
if(tag.tagged == team.team_id){
return team
}
})
},
This method is supposed to return the tags based off of the team id. i the html i have this
:class="{'taglimit' : countTags(team).length >= 3}"
which will add the "taglimit" class if the count is 3 or greater.
SECOND UPDATE:
When I run this query in the created hook i have issues
let tagRef = db.collection('tags')
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.onSnapshot(snapshot => {
this.tags = []
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.tags.push(docs.data())
})
})
but when I run this query I don't
let tagRef = db.collection('tags')
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.get().then((snapshot) => {
snapshot.forEach(doc => {
let tag = doc.data()
tag.id = doc.id
this.tags.push(tag)
})
}).catch(err => {
console.log(err)
})
The problem is I need to update the code every time the tag database changes.
THIRD UPDATE
I think I found the issue. I moved this.tags = [] outside the query and everything appears to be working fine now. so now the query looks like this.
this.tags = []
let tagRef = db.collection('tags')
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.tags.push(docs.data())
console.log(this.tags.length)
})
})
FOURTH UPDATE:
here is the HTML
<v-dialog v-model="dialog" persistent transition="scale-transition" fullscreen light>
<v-btn
slot="activator"
fixed
dark
fab
bottom
right
color="blue-grey darken-2"
class="pulse-button"
>
<v-icon>directions_run</v-icon>
</v-btn>
<v-card color="rgba(224, 224, 224, .95)">
<v-container grid-list-md text-xs-center>
<v-layout row wrap class="tagform-container">
<v-btn dark fab right absolute small color="grey darken-3" @click="dialog = false"><v-icon>close</v-icon></v-btn>
<v-layout justify-center>
<v-card-title class="display-2 font-weight-black">TAG!</v-card-title>
</v-layout>
<v-card-text class="subheading">Select a team you want to tag. Note, you only have one tag per game. Use it wisely!</v-card-text>
<v-flex xs4 class="add-flex" v-for="team in activeTeams" :key="team.id" >
<div class="tag-card"
:class="{'disabled' : activeTag(team).length > 0, 'taglimit' : countTags(team).length >= 3}"
height="100%"
color="white"
style="background:#fff;"
@click="activeTag(team).length > 0 || countTags(team).length >= 3 ? '' : selectedTeam(team)"
>
<v-layout justify-center>
<v-card-title class="title">{{team.team_name}}</v-card-title>
</v-layout>
<v-responsive>
<img class="avatar" v-bind:src="team.url">
</v-responsive>
<v-flex>
<v-card-text class="body-2 text-uppercase">Tap to select</v-card-text>
</v-flex>
</div>
</v-flex>
</v-layout>
</v-container>
</v-card>
</v-dialog>
There is more but this is the part that counts.
Here is some more of the code
data() {
return {
feedback: null,
teams: [],
taggedteam: null,
dialog: false,
stepper: false,
emojiinput: '',
search: '',
e1: 1,
tag: null,
tags: [],
completedtags: [],
tagstates: []
}
},
computed: {
activeTeams: function () {
let thisTeam = this.$store.getters.player.team_id
return this.teams.filter(function (team) {
if(team.team_id !== thisTeam)
return team
})
}
},
One of the Methods:
countTags(team) {
return this.tags.filter(function (tag) {
if(tag.tagged == team.team_id){
return team
}
})
},
finally the created hook
created(){
// get teams
let teamRef = db.collection('teams')
teamRef = teamRef.where('gid', '==', this.$store.getters.gid)
teamRef = teamRef.orderBy('team_id')
teamRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
if(change.type == 'added') {
let docs = change.doc
let leaderRef = db.collection('leaderboard')
leaderRef = leaderRef.where('gid', '==', this.$store.getters.gid)
leaderRef = leaderRef.where('team', '==', docs.data().team_id)
leaderRef = leaderRef.where('missioncomplete', '==', true)
leaderRef.onSnapshot(snapshot => {
if(snapshot.empty) {
// team has not completed the mission so they can still be tagged
this.teams.push(docs.data())
}
})
}
})
})
// get tags
this.tags = []
let tagRef = db.collection('tags')
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.tags.push(docs.data())
})
})
// get tag states
this.tagstates = []
let tagStateRef = db.collection('tagstate')
tagStateRef = tagStateRef.where('gid', '==', this.$store.getters.gid)
tagStateRef = tagStateRef.where('state', '==', true)
tagStateRef = tagStateRef.orderBy('tag')
tagStateRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.tagstates.push(docs.data())
})
})
if(this.$store.getters.player.team_id) {
// check to see if this player has already tagged someone
let tagRef = db.collection('tags')
tagRef = tagRef.where('tagger', '==', this.$store.getters.player.team_id)
tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
tagRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(change => {
let docs = change.doc
this.completedtags.push(docs.data())
})
})
}
}
It's a bit difficult to dive into your code without knowing the exact relationship between teams/tags and their respective limits.
But I've understood from the discussion that you want to change the class of a DOM element if the result of the query is more that 3 documents.
You'll find a possible approach below, which shows how to manange the class change (and also, if needed how to maintain the tags
array in the data
object, ie being reactive to database changes).
<template>
<div :class="{ taglimit: isTagLimit }">Test</div>
</template>
<script>
const fb = require("../firebaseConfig.js");
export default {
data() {
return {
tags: [],
isTagLimit: false
};
},
created: function() {
let tagRef = fb.db.collection("tags");
tagRef = tagRef.where("gid", "==", this.$store.getters.gid);
tagRef.onSnapshot(querySnapshot => {
console.log(querySnapshot.size);
//The next if is sufficient to activate the taglimit class
if (querySnapshot.size > 3) {
this.isTagLimit = true;
} else {
this.isTagLimit = false;
}
//If you want to update the tags property
var t = [];
querySnapshot.forEach(doc => {
t.push(doc.data());
});
this.tags = t;
});
}
};
</script>
<style>
.taglimit {
color: deeppink;
}
</style>
Note that instead of replacing the entire tags
array, you could listen to "atomic" changes in the Query and update the array with the changes, see https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.