В настоящее время я пытаюсь реализовать вход в Google с помощью AngularFireAuth, но не смог. Когда пользователь входит в систему, его запрашивают учетные данные Google - если они не пользователь, они будут превращены в Пользователь и принял, в противном случае их учетные данные будут найдены и приступить к входу. Я использую пользовательский объект пользователя, который хранит дополнительные данные, которые я планирую принять от пользователей, когда они зарегистрируются для будущей разработки.
Однако, когда я пытаюсь получить объект данных, который представляет моего пользовательского пользователя из моего auth.service.ts, он говорит, что определенное поле не определено:
core.js:6014 ERROR Error: Uncaught (in promise): FirebaseError: [code=invalid-argument]: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field at)
FirebaseError: Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field at)
at new FirestoreError (index.cjs.js:351)
at ParseContext.push../node_modules/@firebase/firestore/dist/index.cjs.js.ParseContext.createError (index.cjs.js:20790)
at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseScalarValue (index.cjs.js:21149)
at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (index.cjs.js:21015)
at index.cjs.js:21031
at forEach (index.cjs.js:455)
at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseObject (index.cjs.js:21030)
at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseData (index.cjs.js:20984)
at UserDataConverter.push../node_modules/@firebase/firestore/dist/index.cjs.js.UserDataConverter.parseMergeData (index.cjs.js:20853)
at DocumentReference.push../node_modules/@firebase/firestore/dist/index.cjs.js.DocumentReference.set (index.cjs.js:21836)
at resolvePromise (zone-evergreen.js:797)
at zone-evergreen.js:707
at fulfilled (tslib.es6.js:70)
at ZoneDelegate.invoke (zone-evergreen.js:359)
at Object.onInvoke (core.js:39699)
at ZoneDelegate.invoke (zone-evergreen.js:358)
at Zone.run (zone-evergreen.js:124)
at zone-evergreen.js:855
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:39680)
Однако, когда я просматриваю моего пользовательского пользователя, мой объект Поле at имеет определенный тип, который является строкой:
export interface User {
uid: string;
at: string;
fName: string;
lName: string;
email: string;
occupation: string;
friendCount: number;
collabCount: number;
aboutMe?: string;
displayName?: string;
photoURL?: string;
}
Это мой auth.service.ts:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { User } from './user.model';
import { auth } from 'firebase/app';
import { AngularFireAuth } from '@angular/fire/auth';
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { Observable, of } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthService {
user$: Observable<User>;
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router
) {
this.user$ = this.afAuth.authState.pipe(
switchMap(user => {
if (user) {
return this.afs.doc<User>(`users/${user.uid}`).valueChanges();
} else {
return of(null);
}
})
);
}
async googleSignin() {
const provider = new auth.GoogleAuthProvider();
const credential = await this.afAuth.auth.signInWithPopup(provider);
return this.updateUserData(credential.user);
}
async signOut() {
await this.afAuth.auth.signOut();
return this.router.navigate(['/']);
}
private updateUserData(user) {
// Sets user data to firestore on login
const userRef: AngularFirestoreDocument<User> = this.afs.doc(`users/${user.uid}`);
const data: User = {
uid: user.uid,
at: user.at,
fName: user.fName,
lName: user.lName,
email: user.email,
occupation: user.occupation,
friendCount: user.friendCount,
collabCount: user.collabCount,
aboutMe: user.aboutMe,
displayName: user.displayName,
photoURL: user.photoURL
};
return userRef.set(data, {merge: true});
}
}
Вот компонент, который использует аутентификацию .service:
(log-in.component. html)
<div *ngIf="auth.user$ | async; then authenticated else guest">
<!-- template will replace this div -->
</div>
<!-- User NOT logged in -->
<ng-template #guest>
<h3>You must be new around here...</h3>
<p>Login to get started.</p>
<button (click)="auth.googleSignin()">
Connect Google
</button>
</ng-template>
<!-- User logged in -->
<ng-template #authenticated>
<div *ngIf="auth.user$ | async as user">
<h3>Howdy, {{ user.displayName }}</h3>
<img [src]="user.photoURL">
<p>UID: {{ user.uid }}</p>
<button (click)="auth.signOut()">Logout</button>
</div>
</ng-template>
(log-in.component.ts)
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../services/auth.service';
@Component({
selector: 'app-log-in',
templateUrl: './log-in.component.html',
styleUrls: ['./log-in.component.scss']
})
export class LogInComponent implements OnInit {
constructor(public auth: AuthService) { }
ngOnInit() {
}
}
Еще одна важная деталь Я заметил, что когда я удаляю поле «at» из В моем пользовательском интерфейсе пользователя и в моем объекте данных в auth.service в сообщении об ошибке будет указано, что неопределенное поле - это «fName», то есть поле, следующее за UID, аналогично полю «at». Поэтому меня интересует, не использую ли я какой-то неправильный синтаксис, из-за которого следующие поля, которые появляются после начального поля UID, не определены.
Не стесняйтесь, дайте мне знать, если вам нужен дополнительный код для дальнейшего понимаю мое решение и спасибо, что нашли время для доступа к моей проблеме.