🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Firebase Authentication

Firebase Authenticationは、Firebaseを利用したユーザーの認証機能です。バックエンドサービス、SDK、アプリでのユーザー認証に使用できるUIライブラリが用意されています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Q&A

解決済

2回答

1661閲覧

メール、パスワード認証が失敗してしまいます。

riki01

総合スコア10

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Firebase Authentication

Firebase Authenticationは、Firebaseを利用したユーザーの認証機能です。バックエンドサービス、SDK、アプリでのユーザー認証に使用できるUIライブラリが用意されています。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

0グッド

0クリップ

投稿2021/02/22 13:33

###課題
メール、パスワード認証でアカウントを登録しようとすると以下の様なエラーが出てしまいます。
フロントはNuxt.js/Vue.js,バックエンドはFirebaseで実装しております。
イメージ説明
イメージ説明

###原因
元々ログイン画面にリダイレクトしていたのを、別ページへ変えたことでこのエラーが発生する様になりました。しかし、他のGoogleログインや匿名ログインは問題なく動いております。

register.vue

<template> <v-app> <v-container> <v-row justify="center"> <v-col cols="12" sm="8" md="6"> <h2 class="text-center subtitle-1 font-weight-bold mb-2">メールアドレスで登録</h2> <v-row> <v-col> <v-tabs v-model="tab" background-color="transparent" color="blue accent-2" grow class="mb-3"> <v-tab to="/login"> ログイン </v-tab> <v-tab to="/register"> アカウント登録 </v-tab> </v-tabs> <v-row> <v-col sm="12"> <v-card flat> <v-card-text class="pa-0"> <v-form ref="register_form" v-model="register_valid" lazy-validation> <v-text-field v-model="register_email" label="メールアドレス" :rules="emailRules" required validate-on-blur /> <v-text-field ref="register_password" v-model="register_password" label="パスワード" required :append-icon="show_registerPassword ? 'mdi-eye' : 'mdi-eye-off'" :type="show_registerPassword ? 'text' : 'password'" :rules="register_passwordRules" validate-on-blur loading @click:append="show_registerPassword = !show_registerPassword" > <template #progress> <v-progress-linear :value="score.value" :color="score.color" absolute height="2" /> </template> </v-text-field> <v-text-field v-model="register_password_again" label="パスワード(確認)" required :append-icon="show_registerPassword ? 'mdi-eye' : 'mdi-eye-off'" :type="show_registerPassword ? 'text' : 'password'" validate-on-blur :rules="register_passwordAgainRules" @click:append="show_registerPassword = !show_registerPassword" /> <v-alert v-if="registerErrorMsg" dense text type="error"> {{ registerErrorMsg }} </v-alert> <v-btn :disabled="!register_valid" color="blue darken-3" class="mr-4 white--text" @click="email_register()" > 登録 </v-btn> </v-form> </v-card-text> </v-card> </v-col> </v-row> <v-divider class="my-8" /> <v-row> <v-col sm="12"> <h2 class="text-center subtitle-1 font-weight-bold mb-2">その他のアカウントでログイン</h2> </v-col> </v-row> <SocialLogin /> </v-col> </v-row> </v-col> </v-row> </v-container> </v-app> </template> <script> import zxcvbn from 'zxcvbn'; import SocialLogin from '../components/SocialLogin.vue'; // import store from '../store/index'; export default { // store, components: { SocialLogin }, layout: 'signin', data() { return { registerErrorMsg: '', tab: null, register_valid: true, register_email: '', register_password: '', register_password_again: '', emailRules: [ v => { if (v) { return /.+@.+..+/.test(v) || '有効なメールアドレスを入力してください'; } else { return true; } } ], register_passwordRules: [ v => !!v || 'パスワードを入力してください', v => zxcvbn(v).score >= 3 || '大文字・小文字・数字・記号を混ぜた強いパスワードにしてください' ], register_passwordAgainRules: [ v => { if (v) { return this.$refs.register_password.value === v || 'パスワードと一致しません'; } else { return true; } } ], show_registerPassword: false }; }, computed: { progress() { return this.score.value; }, score() { const result = zxcvbn(this.register_password); switch (result.score) { case 4: return { color: 'green', value: 100 }; case 3: return { color: 'light-green lighten-1', value: 75 }; case 2: return { color: 'amber accent-2', value: 50 }; case 1: return { color: 'deep-orange lighten-1', value: 25 }; default: return { color: 'red darken-3', value: 0 }; } } }, methods: { email_register() { if (this.$refs.register_form.validate()) { this.$store .dispatch('signUp', { email: this.register_email, password: this.register_password }) .then(() => { this.register_email = ''; this.register_password = ''; this.$router.push({ name: 'index', params: { dashboard_msg: true, dashboard_msg_text: 'アカウントの登録が完了しました。' } }); }) .catch(err => { console.error(err); if (err.code === 'auth/email-already-in-use') { this.registerErrorMsg = 'このメールアドレスは既に登録されています。'; } else if (err.code === 'auth/invalid-email') { this.registerErrorMsg = '無効なメールアドレスです。'; } else { this.registerErrorMsg = 'エラーにより登録できませんでした。'; } }); } } } }; </script>

index.js

import { auth } from '../plugins/firebase'; export const strict = false; export const state = () => ({ user: null }); export const mutations = { setUser(state, payload) { state.user = payload; } }; export const actions = { signUp({ email, password }) { return auth().createUserWithEmailAndPassword(email, password); }, signInWithEmail({ email, password }) { return auth().signInWithEmailAndPassword(email, password); }, signInWithGoogle() { return auth().signInWithPopup(new auth.GoogleAuthProvider()); }, signInWithGuest() { return auth().signInAnonymously(); }, signOut() { return auth().signOut(); } }; export const getters = { user(state) { return state.user; }, isAuthenticated(state) { return !!state.user; } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

こちらやっと解決いたしました。
原因はindex.jsの以下の部分でcommitが抜けてしまっていたことです。

export const actions = { signUp(commit, { email, password }) { return auth().createUserWithEmailAndPassword(email, password); }, signInWithEmail(commit, { email, password }) { return auth().signInWithEmailAndPassword(email, password); },

投稿2021/03/02 12:23

riki01

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

問題なく動いている、というところから検証をやり直してみよう。
そして、その動いてるところからどういう変更をしたんでしょうか。

投稿2021/02/22 13:51

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

riki01

2021/02/22 14:01

ご返信ありがとうございます。 >問題なく動いている、というところから検証をやり直してみよう。 そして、その動いてるところからどういう変更をしたんでしょうか。 →すみません、こちらについてですが、今まで別画面の実装をしており、気が付いたらログインできなくなっていました。 そして、ログイン関連の変更といえばリダイレクトのページを、このログイン画面からtop.vueへ変更したのみです。 top.vue <template> <v-app> <div class="header"> <v-btn text absolute right class="auth text-right"> <!-- <nuxt-link to="/register" class="auth__register"> 新規登録 </nuxt-link> --> <nuxt-link to="/login" class="auth__login"> ログイン </nuxt-link> </v-btn> <!-- <nuxt-link to="/top" /> --> <!-- <v-img /> --> </div> </v-app> </template> 曖昧な質問で申し訳ありません。 〜省略
y_waiwai

2021/02/22 14:04

ならその問題なく動く、というところに戻してみてはいかがでしょう
gambaldia

2021/02/22 15:41

client.jsというソースがあるなら、それも貼ってください。
riki01

2021/02/22 15:51

@gembaldia ご返信ありがとうございます。 承知致しました。 client.js import Vue from 'vue' import fetch from 'unfetch' import middleware from './middleware.js' import { applyAsyncData, promisify, middlewareSeries, sanitizeComponent, resolveRouteComponents, getMatchedComponents, getMatchedComponentsInstances, flatMapComponents, setContext, getLocation, compile, getQueryDiff, globalHandleError, isSamePath } from './utils.js' import { createApp, NuxtError } from './index.js' import fetchMixin from './mixins/fetch.client' import NuxtLink from './components/nuxt-link.client.js' // should be included after ./index.js // Fetch mixin if (!Vue.__nuxt__fetch__mixin__) { Vue.mixin(fetchMixin) Vue.__nuxt__fetch__mixin__ = true } // Component: <NuxtLink> Vue.component(NuxtLink.name, NuxtLink) Vue.component('NLink', NuxtLink) if (!global.fetch) { global.fetch = fetch } // Global shared references let _lastPaths = [] let app let router let store // Try to rehydrate SSR data from window const NUXT = window.__NUXT__ || {} Object.assign(Vue.config, {"silent":false,"performance":true}) const logs = NUXT.logs || [] if (logs.length > 0) { const ssrLogStyle = 'background: #2E495E;border-radius: 0.5em;color: white;font-weight: bold;padding: 2px 0.5em;' console.group && console.group ('%cNuxt SSR', ssrLogStyle) logs.forEach(logObj => (console[logObj.type] || console.log)(...logObj.args)) delete NUXT.logs console.groupEnd && console.groupEnd() } // Setup global Vue error handler if (!Vue.config.$nuxt) { const defaultErrorHandler = Vue.config.errorHandler Vue.config.errorHandler = async (err, vm, info, ...rest) => { // Call other handler if exist let handled = null if (typeof defaultErrorHandler === 'function') { handled = defaultErrorHandler(err, vm, info, ...rest) } if (handled === true) { return handled } if (vm && vm.$root) { const nuxtApp = Object.keys(Vue.config.$nuxt) .find(nuxtInstance => vm.$root[nuxtInstance]) // Show Nuxt Error Page if (nuxtApp && vm.$root[nuxtApp].error && info !== 'render function') { const currentApp = vm.$root[nuxtApp] // Load error layout let layout = (NuxtError.options || NuxtError).layout if (typeof layout === 'function') { layout = layout(currentApp.context) } if (layout) { await currentApp.loadLayout(layout).catch(() => {}) } currentApp.setLayout(layout) currentApp.error(err) } } if (typeof defaultErrorHandler === 'function') { return handled } // Log to console if (process.env.NODE_ENV !== 'production') { console.error(err) } else { console.error(err.message || err) } } Vue.config.$nuxt = {} } Vue.config.$nuxt.$nuxt = true const errorHandler = Vue.config.errorHandler || console.error // Create and mount App createApp(null, NUXT.config).then(mountApp).catch(errorHandler) function componentOption (component, key, ...args) { if (!component || !component.options || !component.options[key]) { return {} } const option = component.options[key] if (typeof option === 'function') { return option(...args) } return option } function mapTransitions (toComponents, to, from) { const componentTransitions = (component) => { const transition = componentOption(component, 'transition', to, from) || {} return (typeof transition === 'string' ? { name: transition } : transition) } const fromComponents = from ? getMatchedComponents(from) : [] const maxDepth = Math.max(toComponents.length, fromComponents.length) const mergedTransitions = [] for (let i=0; i<maxDepth; i++) { // Clone original objects to prevent overrides const toTransitions = Object.assign({}, componentTransitions(toComponents[i])) const transitions = Object.assign({}, componentTransitions(fromComponents[i])) // Combine transitions & prefer `leave` properties of "from" route Object.keys(toTransitions) .filter(key => typeof toTransitions[key] !== 'undefined' && !key.toLowerCase().includes('leave')) .forEach((key) => { transitions[key] = toTransitions[key] }) mergedTransitions.push(transitions) } return mergedTransitions } async function loadAsyncComponents (to, from, next) { // Check if route changed (this._routeChanged), only if the page is not an error (for validate()) this._routeChanged = Boolean(app.nuxt.err) || from.name !== to.name this._paramChanged = !this._routeChanged && from.path !== to.path this._queryChanged = !this._paramChanged && from.fullPath !== to.fullPath this._diffQuery = (this._queryChanged ? getQueryDiff(to.query, from.query) : []) if ((this._routeChanged || this._paramChanged) && this.$loading.start && !this.$loading.manual) { this.$loading.start() } try { if (this._queryChanged) { const Components = await resolveRouteComponents( to, (Component, instance) => ({ Component, instance }) ) // Add a marker on each component that it needs to refresh or not const startLoader = Components.some(({ Component, instance }) => { const watchQuery = Component.options.watchQuery if (watchQuery === true) { return true } if (Array.isArray(watchQuery)) { return watchQuery.some(key => this._diffQuery[key]) } if (typeof watchQuery === 'function') { return watchQuery.apply(instance, [to.query, from.query]) } return false }) if (startLoader && this.$loading.start && !this.$loading.manual) { this.$loading.start() } } // Call next() next() } catch (error) { const err = error || {} const statusCode = err.statusCode || err.status || (err.response && err.response.status) || 500 const message = err.message || '' // Handle chunk loading errors // This may be due to a new deployment or a network problem if (/^Loading( CSS)? chunk (\d)+ failed./.test(message)) { window.location.reload(true /* skip cache */) return // prevent error page blinking for user } this.error({ statusCode, message }) this.$nuxt.$emit('routeChanged', to, from, err) next() } } function applySSRData (Component, ssrData) { if (NUXT.serverRendered && ssrData) { applyAsyncData(Component, ssrData) } Component._Ctor = Component return Component }
riki01

2021/02/22 15:51

// Get matched components function resolveComponents (router) { const path = getLocation(router.options.base, router.options.mode) return flatMapComponents(router.match(path), async (Component, _, match, key, index) => { // If component is not resolved yet, resolve it if (typeof Component === 'function' && !Component.options) { Component = await Component() } // Sanitize it and save it const _Component = applySSRData(sanitizeComponent(Component), NUXT.data ? NUXT.data[index] : null) match.components[key] = _Component return _Component }) } function callMiddleware (Components, context, layout) { let midd = ["authenticated"] let unknownMiddleware = false // If layout is undefined, only call global middleware if (typeof layout !== 'undefined') { midd = [] // Exclude global middleware if layout defined (already called before) layout = sanitizeComponent(layout) if (layout.options.middleware) { midd = midd.concat(layout.options.middleware) } Components.forEach((Component) => { if (Component.options.middleware) { midd = midd.concat(Component.options.middleware) } }) } midd = midd.map((name) => { if (typeof name === 'function') { return name } if (typeof middleware[name] !== 'function') { unknownMiddleware = true this.error({ statusCode: 500, message: 'Unknown middleware ' + name }) } return middleware[name] }) if (unknownMiddleware) { return } return middlewareSeries(midd, context) } async function render (to, from, next) { if (this._routeChanged === false && this._paramChanged === false && this._queryChanged === false) { return next() } // Handle first render on SPA mode let spaFallback = false if (to === from) { _lastPaths = [] spaFallback = true } else { const fromMatches = [] _lastPaths = getMatchedComponents(from, fromMatches).map((Component, i) => { return compile(from.matched[fromMatches[i]].path)(from.params) }) } // nextCalled is true when redirected let nextCalled = false const _next = (path) => { if (from.path === path.path && this.$loading.finish) { this.$loading.finish() } if (from.path !== path.path && this.$loading.pause) { this.$loading.pause() } if (nextCalled) { return } nextCalled = true next(path) } // Update context await setContext(app, { route: to, from, next: _next.bind(this) }) this._dateLastError = app.nuxt.dateErr this._hadError = Boolean(app.nuxt.err) // Get route's matched components const matches = [] const Components = getMatchedComponents(to, matches) // If no Components matched, generate 404 if (!Components.length) { // Default layout await callMiddleware.call(this, Components, app.context) if (nextCalled) { return } // Load layout for error page const errorLayout = (NuxtError.options || NuxtError).layout const layout = await this.loadLayout( typeof errorLayout === 'function' ? errorLayout.call(NuxtError, app.context) : errorLayout ) await callMiddleware.call(this, Components, app.context, layout) if (nextCalled) { return } // Show error page app.context.error({ statusCode: 404, message: 'This page could not be found' }) return next() } // Update ._data and other properties if hot reloaded Components.forEach((Component) => { if (Component._Ctor && Component._Ctor.options) { Component.options.asyncData = Component._Ctor.options.asyncData Component.options.fetch = Component._Ctor.options.fetch } }) // Apply transitions this.setTransitions(mapTransitions(Components, to, from)) try { // Call middleware await callMiddleware.call(this, Components, app.context) if (nextCalled) { return } if (app.context._errored) { return next() } // Set layout let layout = Components[0].options.layout if (typeof layout === 'function') { layout = layout(app.context) } layout = await this.loadLayout(layout) // Call middleware for layout await callMiddleware.call(this, Components, app.context, layout) if (nextCalled) { return } if (app.context._errored) { return next() } // Call .validate() let isValid = true try { for (const Component of Components) { if (typeof Component.options.validate !== 'function') { continue } isValid = await Component.options.validate(app.context) if (!isValid) { break } } } catch (validationError) { // ...If .validate() threw an error this.error({ statusCode: validationError.statusCode || '500', message: validationError.message }) return next() } // ...If .validate() returned false if (!isValid) { this.error({ statusCode: 404, message: 'This page could not be found' }) return next() } let instances // Call asyncData & fetch hooks on components matched by the route. await Promise.all(Components.map(async (Component, i) => { // Check if only children route changed Component._path = compile(to.matched[matches[i]].path)(to.params) Component._dataRefresh = false const childPathChanged = Component._path !== _lastPaths[i] // Refresh component (call asyncData & fetch) when: // Route path changed part includes current component // Or route param changed part includes current component and watchParam is not `false` // Or route query is changed and watchQuery returns `true` if (this._routeChanged && childPathChanged) { Component._dataRefresh = true } else if (this._paramChanged && childPathChanged) { const watchParam = Component.options.watchParam Component._dataRefresh = watchParam !== false } else if (this._queryChanged) { const watchQuery = Component.options.watchQuery if (watchQuery === true) { Component._dataRefresh = true } else if (Array.isArray(watchQuery)) { Component._dataRefresh = watchQuery.some(key => this._diffQuery[key]) } else if (typeof watchQuery === 'function') { if (!instances) { instances = getMatchedComponentsInstances(to) } Component._dataRefresh = watchQuery.apply(instances[i], [to.query, from.query]) } } if (!this._hadError && this._isMounted && !Component._dataRefresh) { return } const promises = [] const hasAsyncData = ( Component.options.asyncData && typeof Component.options.asyncData === 'function' ) const hasFetch = Boolean(Component.options.fetch) && Component.options.fetch.length const loadingIncrease = (hasAsyncData && hasFetch) ? 30 : 45 // Call asyncData(context) if (hasAsyncData) { const promise = promisify(Component.options.asyncData, app.context) promise.then((asyncDataResult) => { applyAsyncData(Component, asyncDataResult) if (this.$loading.increase) { this.$loading.increase(loadingIncrease) } }) promises.push(promise) } // Check disabled page loading this.$loading.manual = Component.options.loading === false
riki01

2021/02/22 15:52

長々と申し訳ありません。 是非宜しくお願い致します。
gambaldia

2021/02/22 16:18

こんなに長いとは思いませんでした。ごめんなさい。 コンソールに出ているエラーメッセージに client.js:79 とありましたので、当該箇所を見たかっただけです。 createUserWithEmailAndPasswordの1つ目の引数 emailがnull だと出てますから、それを追いかければ原因がみつかるのではないでしょうか。
riki01

2021/02/23 04:12

@gambaldia >コンソールに出ているエラーメッセージに client.js:79 とありましたので、当該箇所を見たかっただけです。 申し訳ありません、抜粋すべきでした。 ======================================= // Log to console if (process.env.NODE_ENV !== 'production') { console.error(err)←ここが表示されております。 } else { console.error(err.message || err) } ================================ >createUserWithEmailAndPasswordの1つ目の引数 emailがnull だと出てますから、それを追いかければ原因がみつかるのではないでしょうか。 ありがとうございます。 もう1度調査をしてみます。
hoshi-takanori

2021/02/24 01:49

そこはエラーハンドラなので、実際にエラーが起きた場所ではないですよね。 console.log(err.stack); を追加して、スタックトレースを表示してみては。
riki01

2021/02/24 07:06

@hoshi-takanoriさん ご返信ありがとうございます! 承知致しました!もう一度調査してみます! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問