Как использовать Vue Js роутер в функции firestore docChanges - PullRequest
1 голос
/ 19 февраля 2020

Я разрабатываю онлайн-игру для 2 игроков, используя Vue js и Firestore.

Игра начинается следующим образом: Активный пользователь выберет случайного человека из онлайн пользователи и играют в игры с ним.

Когда нажата кнопка новой игры;

  1. Случайный игрок будет выбран из онлайн-пользователей.
  2. Будет создана новая игровая комната: номер игры и информация об игроке будут сохранены в базе данных пожарного магазина.
  3. Для выбранного случайного пользователя будут совпадать номер игры и информация об оппоненте.
  4. Оба пользователя будут перенаправлены на страницу игры.

Мои коды

import db from "@/firebase/init";
export default {
    name: "Home",
    data() {
        return {
            activeUsers: [],
            currentUser: null,
            opponent: null,
            gameNo: null
        };
    },
    created() {
        this.currentUser = this.$session.get("user");
        this.createOnlineUser();
        this.getOnlineUsers();
    },
    methods: {
        createOnlineUser() {
            let ref = db.collection("game_users").doc(this.currentUser.email);
            ref.get().then(doc => {
                if (!doc.exists) {
                    ref.set({
                        user_id: this.currentUser.id,
                        username: this.currentUser.username,
                        is_play: false
                    });
                }
            });
        },
        getOnlineUsers() {
            db.collection("game_users")
                .where("is_play", "==", false)
                .onSnapshot(snapshot => {
                    snapshot.docChanges().forEach(change => {
                        let doc = change.doc;

                        var user = {
                            user_id: doc.data().user_id,
                            username: doc.data().username,
                            email: doc.id
                        };

                        if (change.type === "added") {
                            if (doc.data().user_id != this.currentUser.id) {
                                let userIndex = this.activeUsers.findIndex(
                                    element => element.user_id == user.user_id
                                );
                                if (userIndex === -1) {
                                    this.activeUsers.push(user);
                                }
                            }
                        } else if (change.type === "removed") {
                            this.activeUsers = this.activeUsers.filter(element => {
                                return element.user_id != user.user_id;
                            });
                        }
                    });
                });
        },
        newGame() {
            this.opponent = this.randomUser();
            this.createGameRoom();
        },
        createGameRoom() {
            this.gameNo = Date.now();
            db.collection("game_rooms")
                .add({
                    gameNo: this.gameNo,
                    players: [this.currentUser.email, this.opponent.email],
                })
                .then(() => {
                    this.addGameNoSession();
                })
                .then(() => {
                    this.createGameAndOpponent();
                });
        },
        createGameAndOpponent() {
            db.collection("game_rooms").onSnapshot(snapshot => {
                snapshot.docChanges().forEach(change => {
                    if (change.type == "added") {
                        let doc = change.doc;
                        let players = doc.data().players;
                        let currentUserIndex = players.indexOf(this.currentUser.email);
                        if (currentUserIndex != -1) {
                            if (!this.$session.exists("gameNo")) {
                                this.gameNo = doc.data().gameNo;
                                this.addGameNoSession();
                            }
                        }
                        this.addOpponentSession(currentUserIndex, players);
                        this.$router.push({ name: "Game" });
                    }
                });
            });
        },
        addGameNoSession() {
            this.$session.set("gameNo", this.gameNo);
        },
        randomUser() {
            var item = this.activeUsers[
                Math.floor(Math.random() * this.activeUsers.length)
            ];
            return item;
        },
        addOpponentSession(currentUserIndex, players) {
            let opponent = null,
                opponentIndex = null;
            if (currentUserIndex == 0) {
                opponentIndex = 1;
            } else {
                opponentIndex = 0;
            }
            opponent = this.activeUsers.find(
                user => user.email === players[opponentIndex]
            );
            this.$session.set("opponent", opponent);
        },
    }
};
<template>
  <div id="home">
    <Navbar />
    <div class="home container">
      <div class="card">
        <a  @click="newGame"> New Game
        </a>
      </div>
    </div>
  </div>
</template>

Vue Маршрутизатор - индекс. js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Game from '../views/Game.vue'
import Login from '../views/auth/Login.vue'
import Signup from '../views/auth/Signup.vue'
Vue.use(VueRouter)



const routes = [{
        path: '/',
        name: 'Home',
        component: Home,
        meta: {
            requiresAuth: true
        }
    }, {
        path: '/game',
        name: 'Game',
        component: Game,
        meta: {
            requiresAuth: true
        }
    },
    {
        path: '/login',
        name: 'Login',
        component: Login
    },
    {
        path: '/signup',
        name: 'Signup',
        component: Signup
    }

]

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
})


router.beforeEach((to, from, next) => {
    if (to.matched.some(rec => rec.meta.requiresAuth)) {

        if (Vue.prototype.$session.exists('user')) {
            next()
        } else {
            next({ name: 'Login' })
        }
    } else {
        if (Vue.prototype.$session.exists('user')) {

            if (to.name == "Login" || to.name == "Signup") {
                next({ name: 'Home' })
            }
        }
        next()
    }
})

export default router

Я проверяю внутри функции createGameAndOpponent:

Если есть изменение в "game_rooms" или была создана новая игра, найдите оппонента из онлайн-пользователей и перенаправьте обоих пользователей на страницу игры. Но здесь есть ошибка при перенаправлении. Страница не перенаправляется и выдает следующую ошибку:

Но я получаю ошибку ниже

"Uncaught (in обещание)"

Сведения об ошибке:

vue -router.esm. js: 2086 Uncaught (в обещании) NavigationDuplicated {_name: «NavigationDuplicated», имя: «NavigationDuplicated», сообщение: «Переход к текущему местоположению (« / game ») не разрешен», стек: «Ошибка» в новом NavigationDuplicated (webpack-int… c / views / Home. vue? Vue & type = script & lang = js &: 175: 31) "} _ name:« NavigationDuplicated »name:« NavigationDuplicated »сообщение:« Переход к текущему местоположению («/ game») не разрешен »стек:« Ошибка »в новом NavigationDuplicated (webpack-internal: ///./node_modules/vue-router/dist/vue-router.esm.js: 2009: 14) ↵ в HTML5History.confirmTransition (webpack-internal: /// ./node_modules/vue-router/dist/vue-router.esm.js:2125:18)↵ в HTML5History.transitionTo (webpack-internal: ///./node_modu les / vue -router / dist / vue -router.esm. js: 2069: 8) ↵ на HTML5History.pu sh (внутренний пакет: ///./node_modules/vue- router / dist / vue -router.esm. js: 2400: 10) ↵ на eval (webpack-internal: ///./node_modules/vue-router/dist/vue-router.esm . js: 2812: 22) ↵ в новом Promise () ↵ на VueRouter.pu sh (внутренний пакет: ///./node_modules/vue-router/dist/vue-router.esm . js: 2811: 12) ↵ на eval (webpack-internal: ///./node_modules/cache-loader/dist/cjs.js?! ./Node_modules/vue- loader / lib / index. js?! ./ src / views / Home. vue? vue & type = script & lang = js &: 204: 26) ↵ в Array.forEach () ↵ в Object.eval [как следующий] ( WebPack-внутренний:?!?! ///./node_modules/cache-loader/dist/cjs.js ./node_modules/vue-loader/lib/index.js ./ src / views / Home. vue? vue & type = script & lang = js &: 175: 31) " proto : ошибка
eval @ vue -router.esm. js: 2086
abort @ vue -router.esm. js: 2117
Подтверждение перехода @ vue -router.esm. js: 2125 * 10 63 * transitionTo @ vue -router.esm. js: 2069
pu sh @ vue -router.esm. js: 2400
eval @ vue -router.esm . js: 2812
pu sh @ vue -router.esm. js: 2811
eval @ cjs. js?! ./ node_modules / vue -loader / lib / index. js?! ./ src / views / Home. vue? vue & type = script & lang = js &: 204
eval @ cjs. js?!. /node_modules/vue-loader/lib/index.js?!./src/views/Home.vue?vue&type=script&lang=js&:175
next @ index. cjs . js: 22426
eval @ index. cjs. js: 20155
setTimeout (asyn c)
AsyncObserver.scheduleEvent @ index. cjs . js: 20153
AsyncObserver.next @ index. cjs. js: 20142
QueryListener.raiseInitialEvent @ index. cjs. js: 17098
QueryListener.onViewSnapshot @ index. cjs. js: 17033
EventManager.listen @ index. cjs. js: 16889
eval @ index. cjs. js: 20004
eval @ index. cjs . js: 1698
Promise.then (asyn c)
AsyncQueue.enqueueInternal @ index. cjs. js: 1696
AsyncQueue.enqueue @ index. cjs. js: 1692
AsyncQueue.enqueueAndForget @ index. cjs. js: 1639
FirestoreClient.listen @ index. cjs. js : 20003
Query.onSnapshotInternal @ index. cjs. js: 22432
Query.onSnapshot @ index. cjs. js: 22413
oyunVeRakipTanimla @ * . 1218 *js 1219 * ./ node_modules / vue -loader / Lib / индекс js ./ ЦСИ / просмотров / Главная vue вю & тип = сценарий & LANG = JS &:!.?!.? 174
eval @ cjs. js?! ./ node_modules / vue -loader / lib / index. js?! ./ src / views / Home. vue? Vue & type = script & lang = js &: 155
P romise.then (asyn c)
createGameRoom @ cjs. js?! ./ node_modules / vue -loader / lib / index. js?! ./ src / views /Home.vue?vue&type=script&lang=js&:154
newGame @ cjs. js?! ./ node_modules / vue -loader / lib / index. js ?! ./src/views/Home.vue?vue&type=script&lang=js&:133
invokeWithErrorHandling @ vue .runtime.esm. js: 1853
invoker @ vue .runtime.esm. js: 2178
original._wrapper @ vue .runtime.esm. js: 6907

Где я делаю ошибки?

Какой метод следует использовать, чтобы направлять обоих пользователей на страницу игры в режиме реального времени?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...