【问题标题】:How to store data under specific user id? Angular&Firebase如何在特定用户 ID 下存储数据? Angular&Firebase
【发布时间】:2021-03-22 08:08:00
【问题描述】:

已经有一段时间了。 我的问题是如何通过当前登录的用户 ID 将数据存储在实时数据库(firebase)中,所以当我从另一个帐户登录时,我看不到该数据(只有我自己的)。 这就是我现在的做法: employee.service.ts:

@Injectable({
providedIn: 'root'
})
export class EmployeeService {
userId: string;

constructor(public firebase: AngularFireDatabase, private datePipe: DatePipe, private afu: 
AngularFireAuth, public clientService: ClientService, public contractsService: ContractsService, 
public maintainerService: MaintainerService) {
  this.afu.authState.subscribe(user=>{
      if(user) this.userId=user.uid;
  })
}

employeeList: AngularFireList<any>;
clientList: AngularFireList<any>;
maintainerList: AngularFireList<any>;
contractList: AngularFireList<any>;
array=[];

form: FormGroup=new FormGroup({
$key: new FormControl(null),
sifra: new FormControl(''),
caseName: new FormControl(''),
department: new FormControl(''),
startDate: new FormControl(new Date()),
startTime: new FormControl(''),
finishTime: new FormControl(''),
isPermanent: new FormControl(false), //nije obavezno
description: new FormControl(''),
remark: new FormControl(''), //nije obavezno
serviceType: new FormControl('1'),
isReplaceable: new FormControl(''),
maintainer: new FormControl(''),
contracts: new FormControl(''),
dnevnica: new FormControl(''),
client: new FormControl('')
});
initializeFormGroup(){
this.form.setValue({
$key: null,
sifra: '',
caseName: '',
department: '',
startDate: '',
startTime: '',
finishTime: '',
isPermanent: false,
description: '',
remark: '',
serviceType: '1',
isReplaceable: '',
maintainer: '',
contracts: '',
dnevnica: '',
client: ''
});
}

getEmployees(){
this.employeeList=this.firebase.list(`employees/${this.userId}`);
return this.employeeList.snapshotChanges();
}

在我的组件文件中:

 ngOnInit(): void {

 this.service.getEmployees().subscribe(
 list=>{
  let array = list.map(item=>{
    let clientName=this.clientService.getClientName(item.payload.val()['client']);
    let maintainerName=this.maintainerService.getMaintainerName(item.payload.val()['maintainer']);
    return{
      $key: item.key,
      clientName,
      maintainerName,
      ...item.payload.val()
    };
  });
  this.listData= new MatTableDataSource(array);
  this.listData.sort=this.sort;
  this.listData.paginator=this.paginator;
  this.listData.filterPredicate=(data, filter)=>{
    return this.displayColumns.some(ele=>{
      return ele != 'actions' && data[ele].toLowerCase().indexOf(filter) != -1;
    });
  }
});
}

当我第一次登录时,一切都很好。当我刷新页面时,我的一切都消失了! 这很奇怪,因为我的数据仍在我的数据库中,但是如果我单击浏览器上的返回按钮并再次输入我的组件,数据又在那里! 提前致谢。

【问题讨论】:

    标签: javascript angular firebase firebase-realtime-database


    【解决方案1】:

    那是因为onAuthStatusChanged(),也就是authState 的代理,返回一个三进制值,而不是二进制。

    由于您使用真值检查来确定用户是否经过身份验证,因此您创建了一个竞争条件,因为您没有等待 SDK 完全初始化。

    constructor(private afu: AngularFireAuth) {
      this.afu.authState.subscribe(user=>{
          if(user) this.userId=user.uid;
      })
    }
    

    由于 Firebase 身份验证是异步的,所以从 authStateonAuthStatusChanged 返回的值可以是以下三个值之一:

    • undefined:JS SDK已初始化,但尚未检查用户的认证状态。
    • null:用户未经身份验证。
    • User Object:用户已通过身份验证。

    您需要做的是等到authState 返回nullUser,如下所示:

    enum AuthState {
      UNKNOWN,
      UNAUTHENTICATED,
      AUTHENTICATED
    }
    
    // This subject will store the user's current auth state
    private _state = new BehaviorSubject<AuthState>(AuthState.UNKNOWN);
    
    constructor(private afu: AngularFireAuth) {
      this.afu.authState.subscribe(user=>{
          if (typeof user === 'undefined') {
             // Do nothing because the user's auth state is unknown
             return;
          } else if (user === null) {
             // User is unauthenticated
             this._state.next(AuthState.UNAUTHENTICATED);
          } else {
             // User is authenticated
             this.userId = user.uid;
             this._state.next(AuthState.AUTHENTICATED);
          }
      })
    }
    
    // Public method to monitor user's auth state
    public state$(): Observable {
      return this._state.asObservable();
    }
    
    

    然后在您的组件中,您需要在调用getEmployees() 之前订阅state$() observable。

    ngOnInit(): void {
      this.service.state$().subscribe((state: AuthState) => {
        // We don't know what the user's auth state is, so exit waiting for an update
        if (state === AuthState.UNKNOWN) {
          return;
        } else if (state === AuthState.UNAUTHENTICATED) {
          // User is unauthenticated so redirect to login or whatever
        } else {
          // User is authenticated, so now we can call getEmployees()
          this.service.getEmployees().subscribe(...);
        }
      });
    }
    

    【讨论】:

    • 布莱恩,谢谢你的详细解释。我会尽我所能在理解的情况下学习这一点。我希望其他有同样问题的人能看到他,再次感谢你,你是最棒的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-15
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 2022-01-21
    • 2015-07-29
    • 2021-04-02
    相关资源
    最近更新 更多