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

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

詳細はこちら
Firebase

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

Ionic

Ionicは、クロスプラットフォームに対応したモバイルアプリ開発のためのオープンソースUIフレームワークです。iOSやAndroid、Webのアプリケーションを1つのコードベースで開発できます。

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

Q&A

解決済

1回答

1205閲覧

ionic + Firebaseのアカウント登録でdisplayNameがnullになる

Gento

総合スコア77

Firebase

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

Ionic

Ionicは、クロスプラットフォームに対応したモバイルアプリ開発のためのオープンソースUIフレームワークです。iOSやAndroid、Webのアプリケーションを1つのコードベースで開発できます。

Angular

Angularは、JavaScriptフレームワークです。AngularJSの後継であり、TypeScriptベースで実装されています。機能ごとに実装を分けやすく、コードの見通しが良いコンポーネント指向です。

0グッド

0クリップ

投稿2019/09/17 11:06

編集2019/09/19 03:26

前提・実現したいこと

新規ユーザー登録をした直後に、ユーザーネームを画面に表示したい。

発生している問題

サインインで登録した直後にfirebaseのデータベース(Firestore)を見ると
・usersコレクションの中にuidがあり
・Authenticationにアカウントが登録されている

サインインで登録した直後ではemailとuidしか存在していなくて、displayNameはnullです。
しかし一度リロードすると、サインイン時に入力した名前がdisplayNameが登録されます。

該当のソースコード

auth.service.ts

typescript

1import { Injectable } from '@angular/core'; 2import { Router } from '@angular/router'; 3import { AngularFireAuth } from '@angular/fire/auth'; 4import { Observable } from 'rxjs'; 5import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore'; 6import { switchMap } from 'rxjs/operators'; 7 8export interface User { 9 uid: string; 10 email: string; 11 displayName?: string; 12 myCustomData?: string; 13 photoURL?: string; 14} 15 16@Injectable({ 17 providedIn: 'root' 18}) 19 20export class AuthService { 21 user$: Observable<User[]>; 22 23 24 constructor( 25 private router: Router, 26 private afs: AngularFirestore, 27 private afAuth: AngularFireAuth 28 ) { 29 this.user$ = this.afAuth.authState.pipe( 30 switchMap(user => { 31 if (user) { 32 this.updateUserData(user); 33 console.log('auth.service ' + user.displayName); 34 return this.afs.doc<User[]>(`users/${user.uid}`).valueChanges(); 35 } else { 36 this.router.navigateByUrl('/auth'); 37 } 38 }) 39 ); 40 } 41 42 async login(email: string, password: string) { 43 await this.afAuth.auth.signInWithEmailAndPassword(email, password) 44 .then((user) => { 45 console.log(user); 46 this.router.navigateByUrl('/'); 47 }) 48 .catch((error) => { 49 console.log(error); 50 this.router.navigateByUrl('/auth'); 51 }); 52 } 53 54 async logout() { 55 await this.afAuth.auth.signOut(); 56 this.router.navigateByUrl('/auth'); 57 } 58 59 updateUserData(user) { 60 // ログイン時にユーザーデータをfirestoreに設定 61 const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`); 62 const data = { 63 uid: user.uid, 64 email: user.email, 65 displayName: user.displayName, 66 photoURL: user.photoURL 67 }; 68 console.log(data); 69 return userRef.set(data, { merge: true }); 70 } 71}

signup.page.ts

typescript

1import { Router } from '@angular/router'; 2import { AuthService } from './../auth/auth.service'; 3import { Component, OnInit } from '@angular/core'; 4import { AngularFireAuth } from '@angular/fire/auth'; 5import { ToastController } from '@ionic/angular'; 6 7@Component({ 8 selector: 'app-signup', 9 templateUrl: './signup.page.html', 10 styleUrls: ['./signup.page.scss'], 11}) 12export class SignupPage implements OnInit { 13 signup: { 14 email: string; 15 password: string; 16 name: string; 17 } = { 18 email: '', 19 password: '', 20 name: '', 21 }; 22 23 24 constructor( 25 private router: Router, 26 private afAuth: AngularFireAuth, 27 private toastCtrl: ToastController, 28 private authService: AuthService 29 ) { } 30 31 ngOnInit() { 32 } 33 34 signUp() { 35 this.afAuth.auth 36 .createUserWithEmailAndPassword(this.signup.email, this.signup.password) 37 .then((created) => { 38 const newUser = created.user; 39 newUser.updateProfile({ 40 displayName: this.signup.name, 41 photoURL: '' 42 }) 43 .catch((error) => { 44 console.log('signUpでエラー: ' + error); 45 this.router.navigateByUrl('/signup'); 46 }) 47 .then(async () => { 48 const toast = await this.toastCtrl.create({ 49 // 入力した名前が表示される 50 message: `${created.user.displayName}さんを登録しました`, 51 duration: 3000 52 }); 53 await toast.present(); 54 this.authService.updateUserData(newUser); 55 }) 56 .catch(async error => { 57 const toast = await this.toastCtrl.create({ 58 message: error.toString(), 59 duration: 3000 60 }); 61 await toast.present(); 62 }); 63 this.router.navigateByUrl('/'); 64 }); 65 } 66 67 goLogin() { 68 this.router.navigateByUrl('/auth'); 69 } 70}

home.page.ts

html

1<ion-header> 2 <ion-toolbar> 3 <ion-title>リスト</ion-title> 4 <ion-buttons slot="end"> 5 <ion-button (click)="logout()"> 6 ログアウト 7 </ion-button> 8 </ion-buttons> 9 </ion-toolbar> 10</ion-header> 11 12<ion-content> 13 <div *ngIf="authService.user$ | async as user"> 14 <!-- user.displayNameは一度リロードした後なら表示される --> 15 <h3>Howdy, {{ user.displayName }}</h3> 16 <p>UID: {{ user.uid }}</p> 17 </div> 18</ion-content> 19

##エラー

「ユーザー登録でdisplayNameがnullになる」とは関係ないかもですが、、、。
ログアウトした時に毎回発生します。コンソールにエラーは出るが、今の所特に問題なく動く。

Uncaught TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable. at subscribeTo (subscribeTo.js:27) at subscribeToResult (subscribeToResult.js:11) at SwitchMapSubscriber._innerSub (switchMap.js:46) at SwitchMapSubscriber._next (switchMap.js:36) at SwitchMapSubscriber.next (Subscriber.js:49) at angularfire2.js:44 at ZoneDelegate.invoke (zone-evergreen.js:359) at Object.onInvoke (core.js:34201) at ZoneDelegate.invoke (zone-evergreen.js:358) at Zone.run (zone-evergreen.js:124)

補足情報(FW/ツールのバージョンなど)

ionic info

Ionic: Ionic CLI : 5.2.8 (/usr/local/lib/node_modules/ionic) Ionic Framework : @ionic/angular 4.8.0 @angular-devkit/build-angular : 0.801.3 @angular-devkit/schematics : 8.1.3 @angular/cli : 8.1.3 @ionic/angular-toolkit : 2.0.0 Utility: cordova-res : 0.6.0 native-run : 0.2.8 System: NodeJS : v10.15.1 (/usr/local/bin/node) npm : 6.4.1 OS : macOS Mojave

##参考にしたサイト
https://fireship.io/lessons/angularfire-google-oauth/

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

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

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

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

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

guest

回答1

0

自己解決

これでいけました

typescript

1signUp() { 2 this.afAuth.auth 3 .createUserWithEmailAndPassword(this.signup.email, this.signup.password) 4 .then(created => { 5 const newUser = created.user; 6 newUser.updateProfile({ 7 displayName: this.signup.name, 8 photoURL: '' 9 }) 10 .then(async () => { 11 console.log('signup ' + this.signup.name); 12 const toast = await this.toastCtrl.create({ 13 message: `${created.user.displayName}さんを登録しました`, 14 duration: 3000 15 }); 16 this.nativeStorage.setItem('email_user', { 17 uid: newUser.uid, 18 name: newUser.displayName, 19 email: newUser.email 20 }); 21 this.authService.updateUserData(created.user); 22 this.router.navigateByUrl('/home'); 23 await toast.present(); 24 }); 25 }) 26 .catch(error => { 27 console.log(error); 28 const code = error.code; 29 let message = 'エラーが発生しました。もう一度お試しください。。。'; 30 if (code === 'auth/email-already-in-use') { 31 message = 'このメールアドレスは既に登録されています。。。'; 32 } 33 this.showAlert(message); 34 }); 35 }

投稿2019/11/15 01:00

Gento

総合スコア77

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問