Vue + Vuex + Firebase serverless realtime chat
up vote
4
down vote
favorite
I am "discovering" Firebase and I'm trying create simple chat with Vue, Vuex and Firebase. But because I'm just starting out with Vue, I need code review or advices from more experienced programmers. I need to know whether this code is properly structured - if it is well written in "Vue way" - and how to make my components better - more universal / better separated from rest of the code.
jsFiddle
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
javascript ecmascript-6 firebase vue.js
add a comment |
up vote
4
down vote
favorite
I am "discovering" Firebase and I'm trying create simple chat with Vue, Vuex and Firebase. But because I'm just starting out with Vue, I need code review or advices from more experienced programmers. I need to know whether this code is properly structured - if it is well written in "Vue way" - and how to make my components better - more universal / better separated from rest of the code.
jsFiddle
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
javascript ecmascript-6 firebase vue.js
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
I am "discovering" Firebase and I'm trying create simple chat with Vue, Vuex and Firebase. But because I'm just starting out with Vue, I need code review or advices from more experienced programmers. I need to know whether this code is properly structured - if it is well written in "Vue way" - and how to make my components better - more universal / better separated from rest of the code.
jsFiddle
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
javascript ecmascript-6 firebase vue.js
I am "discovering" Firebase and I'm trying create simple chat with Vue, Vuex and Firebase. But because I'm just starting out with Vue, I need code review or advices from more experienced programmers. I need to know whether this code is properly structured - if it is well written in "Vue way" - and how to make my components better - more universal / better separated from rest of the code.
jsFiddle
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
var uid = null
var firebaseConfig = {
apiKey: "AIzaSyDGYiab8xoIXIgbFSmLSwXubNL2T3Rr6AQ",
authDomain: "first-steps-6abb2.firebaseapp.com",
databaseURL: "https://first-steps-6abb2.firebaseio.com"
}
var store = new Vuex.Store({
state: {
messages:
},
mutations: {
addMessage (state, message) {
state.messages.push(message)
if (state.messages.length > 10) {
state.messages.shift()
}
}
}
})
var listMessages = {
template: `
<ul class="list-messages">
<li v-for="message in messages">
<span>{{message.time}}</span> {{ message.text }}
</li>
</ul>
`,
data () {
return {
messages: this.$store.state.messages
}
}
}
var addMessage = {
template: `
<div class="add-message">
<label for="message">Add new:</label>
<input id="message" @keyup.enter v-model="message">
<button @click="sendMsg">Send</button>
</div>
`,
data () {
return {
message: ''
}
},
methods: {
sendMsg () {
messages.push().set({
uid: uid,
content: this.message,
timestamp: firebase.database.ServerValue.TIMESTAMP
})
this.message = ''
}
}
}
firebase.initializeApp(firebaseConfig)
firebase.auth().signInAnonymously()
firebase.auth().onAuthStateChanged(function (user) {
if (user) { uid = user.uid }
})
new Vue({
el: '#app',
store,
components: {
listMessages,
addMessage
}
})
var db = firebase.database()
var messages = db.ref('messages')
var query = messages.orderByChild('timestamp').limitToLast(10)
query.on('child_added', function (data) {
store.commit('addMessage', {
uid: data.val().uid,
text: data.val().content,
time: moment(data.val().timestamp).format('hh:mm:ss')
})
})
html, body {
margin: 0;
height: 100%;
}
.container {
min-height: 100%;
position: relative;
}
.list-messages {
position: absolute;
box-sizing: border-box;
width: 100%;
top: 10px;
margin: 0;
padding: 10px;
list-style: none;
}
.list-messages span {
color: lightblue;
}
.add-message {
text-align: center;
position: absolute;
width: 100%;
bottom: 10px;
}
<div id="app" class="container">
<list-messages></list-messages>
<add-message></add-message>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.1.3/firebase-database.js"></script>
javascript ecmascript-6 firebase vue.js
javascript ecmascript-6 firebase vue.js
edited Nov 14 at 4:16
Jamal♦
30.2k11115226
30.2k11115226
asked Jul 24 '17 at 15:31
user145018
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid
is not null
and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.
Since ecmascript-6 is used (e.g. with the template literals) const
could be used instead of var
for any variable that doesn't get re-assigned (e.g. the components, db
, etc.) and let
for other variables (e.g. uid
).
You could also consider providing a key attribute on the v-for
where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.
It is recommended to provide a
key
withv-for
whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1
1https://vuejs.org/v2/guide/list.html#key
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid
is not null
and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.
Since ecmascript-6 is used (e.g. with the template literals) const
could be used instead of var
for any variable that doesn't get re-assigned (e.g. the components, db
, etc.) and let
for other variables (e.g. uid
).
You could also consider providing a key attribute on the v-for
where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.
It is recommended to provide a
key
withv-for
whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1
1https://vuejs.org/v2/guide/list.html#key
add a comment |
up vote
1
down vote
The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid
is not null
and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.
Since ecmascript-6 is used (e.g. with the template literals) const
could be used instead of var
for any variable that doesn't get re-assigned (e.g. the components, db
, etc.) and let
for other variables (e.g. uid
).
You could also consider providing a key attribute on the v-for
where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.
It is recommended to provide a
key
withv-for
whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1
1https://vuejs.org/v2/guide/list.html#key
add a comment |
up vote
1
down vote
up vote
1
down vote
The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid
is not null
and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.
Since ecmascript-6 is used (e.g. with the template literals) const
could be used instead of var
for any variable that doesn't get re-assigned (e.g. the components, db
, etc.) and let
for other variables (e.g. uid
).
You could also consider providing a key attribute on the v-for
where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.
It is recommended to provide a
key
withv-for
whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1
1https://vuejs.org/v2/guide/list.html#key
The code looks pretty straight-forward and I don't spot any obvious simplifications. I would suggest that you add error handling - especially for the case when uid
is not null
and remains that way. Perhaps an error message should be added if the request for the appropriate value fails.
Since ecmascript-6 is used (e.g. with the template literals) const
could be used instead of var
for any variable that doesn't get re-assigned (e.g. the components, db
, etc.) and let
for other variables (e.g. uid
).
You could also consider providing a key attribute on the v-for
where the messages are displayed, but the markup is quite simple for those so it may not add any benefit.
It is recommended to provide a
key
withv-for
whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.1
1https://vuejs.org/v2/guide/list.html#key
answered Nov 13 at 23:02
Sᴀᴍ Onᴇᴌᴀ
7,67561748
7,67561748
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f171044%2fvue-vuex-firebase-serverless-realtime-chat%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown