I’m creating a restaurant reservation app with Nuxt, Laravel API and FirebaseAuthentication.
I created a like/unlike feature that the heart color changes to red if the logged in user clicked a heart button on cards.
The function sometimes works fine but sometimes gets an error at getLikes() in store/auth.js when it’s reloaded.
GET http://localhost:8000/api/v1/users/ 405 (Method Not Allowed)
The API path to get the liked restaurant is api/v1/likes/{user_id}, bit since the user information is not stored, the information is taken according to the following flow.
Get user information. (api/v1/users/{uid})
Get a list of liked restaurants of a logged in user. (api/v1/likes/{user_id})
When I checked the execution history of Vuex, the execution order changed depending on whether it succeeded or failed.
When it succeeded, auth/setUserId is executed faster than likes/setLikedShops.
I think the problem is that the likes/setLikesShops process proceeds without getting the user information, but I don’t get the solution.
How can I make sure that I get the user_id first and then get the favorites?
// plugins/firebase.js
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.LOCAL)
// middleware/auth.js
export default function({store}) {
store.dispatch('auth/onAuth')
}
// pages/index.vue
async mounted() {
await this.$store.dispatch('shop/getShops')
await this.$store.dispatch('likes/getLikes')
return
}
// store/auth.js
export const state = () => ({
userId: '',
userUid: '',
userEmail: '',
loggedIn: false,
})
export const mutations = {
loginStatusChange(state, status) {
state.loggedIn = status
},
setUserUid(state, userUid) {
state.userUid = userUid
},
setUserEmail(state, userEmail) {
state.userEmail = userEmail
},
setUserId(state, userId) {
state.userId = userId
}
}
export const actions = {
login({ commit, dispatch }, payload) {
firebase
.auth()
.signInWithEmailAndPassword(payload.email, payload.password)
.then(async (result) => {
const user = result.user
commit('loginStatusChange', true)
console.log('Login was successful')
commit('setUserUid', user.uid)
commit('setUserEmail', user.email)
await dispatch('getUserInfo', user.uid)
await this.$router.push('/')
})
.catch((error) => {
const errorCode = error.code
console.log('error: ' + errorCode)
})
},
onAuth({ commit, dispatch }) {
firebase.auth().onAuthStateChanged(async user => {
user = user ? user : {}
commit('setUserUid', user.uid)
commit('setUserEmail', user.email)
commit('loginStatusChange', user.uid ? true : false)
await dispatch('getUserInfo', user.uid)
})
},
async getUserInfo({commit}, uid) {
const data = await axios.get(
'http://localhost:8000/api/v1/users/'
+ uid
)
commit('setUserId', data.data.id)
}
}
export const getters = {
isAuthenticated(state) {
return state.loggedIn != false
}
}
// store/likes.js
export const state = () => (
{
likedShops: [],
likedShopIds: []
}
)
export const mutations = {
setLikedShops(state, shops) {
state.likedShops.push(...shops)
},
setLikedShopIds(state) {
state.likedShopIds = state.likedShops.map(obj => obj.shop_id)
console.log('likedShopIds: ' + state.likedShopIds)
}
}
export const actions = {
async getLikes({ rootState, commit }) {
const userUid = await rootState.auth.userUid
const user = await axios.get(
`${process.env.baseUrl}/users/${userUid}`
)
const userId = await user.data.id
const result = await axios.get(
`${process.env.baseUrl}/likes/${userId}`
)
await commit('setLikedShops', result.data)
await commit('setLikedShopIds')
},
}
export const getters = {
getLikedShops: (state) => {
return state.likedShops
},
getLikedShopIds: (state) => {
return state.likedShopIds
}
}