简体   繁体   English

如何在特定用户 ID 下存储数据? Angular&Firebase

[英]How to store data under specific user id? Angular&Firebase

it's been a while.有一阵子了。 My question is how to store data in realtime database (firebase) by current logged in user id, so when I log in from another account, I can't see that data (only my own).我的问题是如何通过当前登录的用户 ID 将数据存储在实时数据库(firebase)中,所以当我从另一个帐户登录时,我看不到该数据(只有我自己的)。 This is how I do it now: employee.service.ts:这就是我现在的做法: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();
}

And in my compoent file:在我的组件文件中:

 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;
    });
  }
});
}

When I login for the first time, everything is good.当我第一次登录时,一切都很好。 When I refresh page, all my keep disappearing, It's pretty strange, since my data is still in my database but if I click back button on my browser and enter my component again.当我刷新页面时,我的所有内容都消失了,这很奇怪,因为我的数据仍在我的数据库中,但是如果我单击浏览器上的后退按钮并再次输入我的组件。 data is there again!数据又来了! Thanks in advance.提前致谢。

That is because onAuthStatusChanged() , which is what authState proxies, returns a trinary value, not binary.那是因为onAuthStatusChanged() ,这是authState代理,返回一个三进制值,而不是二进制。

Since you're using a truthy check to determine if the user is authenticated, you've created a race condition because you're not waiting for the SDK to fully initialize.由于您使用真实检查来确定用户是否已通过身份验证,因此您创建了竞争条件,因为您没有等待 SDK 完全初始化。

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

Since Firebase Auth is asynchronous, the value returned from authState or onAuthStatusChanged can be one of three values:由于 Firebase Auth 是异步的,因此从authStateonAuthStatusChanged返回的值可以是以下三个值之一:

  • undefined : The JS SDK has initialized but hasn't checked the user's authentication status yet. undefined : JS SDK 已经初始化但是还没有检查用户的认证状态。
  • null : The user is unauthenticated. null :用户未经身份验证。
  • User Object : The user is authenticated. User Object :用户已通过身份验证。

What you need to do is wait until authState returns either null or User like this:您需要做的是等到authState返回null或像这样的User

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();
}

Then in your component you need to subscribe to the state$() observable before calling getEmployees() .然后在您的组件中,您需要在调用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(...);
    }
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM