javascript - 如何为匿名用户设置 Firebase 规则以仅读取和写入自己的数据
问题描述
我希望匿名用户只能读取和写入他们自己的数据。我将以下内容作为我的安全规则,但在模拟器和应用程序中出现无法读取错误。
我不确定我是否以正确的方式去做。我的主要目标是将同一用户的新评估嵌套在他们的 uid 下,并使其只能读取、写入和更新自己的评估。
{
"rules": {
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
}
}
这是我的分支目前的样子
这就是我认为完成我需要的事情的样子。 理想的数据库结构
auth.gaurd.ts
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { AuthService } from "../../shared/service/auth.service";
import { Observable } from 'rxjs';
import * as firebase from 'firebase';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
uid: string;
constructor(
public authService: AuthService,
public router: Router
){ }
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
this.authStateListener();
return true;
}
authStateListener() {
// [START auth_state_listener]
firebase.auth().onAuthStateChanged((user) => {
if (user) {
// User is signed in, see docs for a list of available properties
this.uid = user.uid;
console.log("user"+user.isAnonymous)
console.log("uid"+this.uid)
} else {
// User is signed out
return firebase.auth().signOut().then(() => {
localStorage.removeItem('user');
this.router.navigate(['sign-in']);
})
}
});
}
}
auth.service.ts
import { Injectable, NgZone, ViewChild, ElementRef, Component } from '@angular/core';
import { User } from "../service/user";
import { auth } from 'firebase/app';
import { AngularFireAuth } from "@angular/fire/auth";
import { AngularFirestore, AngularFirestoreDocument } from '@angular/fire/firestore';
import { ActivatedRoute, Router } from "@angular/router";
import * as firebase from 'firebase';
import "firebase/auth";
@Injectable({
providedIn: 'root'
})
export class AuthService {
userData: any; // Save logged in user data
@ViewChild('btnLogin') btnLogin: HTMLButtonElement;
constructor(
public afs: AngularFirestore, // Inject Firestore service
public afAuth: AngularFireAuth, // Inject Firebase auth service
public router: Router,
private actRoute: ActivatedRoute,
public ngZone: NgZone // NgZone service to remove outside scope warning
) {
}
anonymousSignIn(){
firebase.auth().signInAnonymously()
.then(()=>{
this.router.navigate(['assessment']);
console.log("clicking")
}).catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log("error here")
});
}
**这是在 Firebase 中推送、读取、更新和删除分支的代码。ReadAssessment 列表应显示匿名用户拥有的所有数据,以便他们阅读。** 火灾评估.service.ts
import { AuthGuard } from './../shared/guard/auth.guard';
import { Injectable } from '@angular/core';
import {AngularFireDatabase, AngularFireList, AngularFireObject} from '@angular/fire/database';
import * as firebase from 'firebase';
import {Business} from '../models/business';
import { ActivatedRoute, Router } from '@angular/router';
import { map } from 'rxjs/internal/operators/map';
import { isNgTemplate } from '@angular/compiler';
@Injectable({
providedIn: 'root'
})
export class FireAssessmentService {
assessmentsRef: AngularFireList<any>; // Reference to Assessment data list, its an Observable
assessmentRef: AngularFireObject<any>; // Reference to assessment object
public database = firebase.database();
public UserAssessmentInput;
public ref;
public actRoute: ActivatedRoute;
public router: Router;
public auth: AuthGuard;
constructor(private db: AngularFireDatabase) {
}
CreateAssessment(business: Business ){
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set(
///this.assessmentsRef.ref('/users').push(
{
busiName: business.busiName
});
}
ReadAssessment(id: string){
this.assessmentRef = this.db.object('users/' + id);
return this.assessmentRef;
}
ReadAssessmentsList(){
this.assessmentsRef = this.db.list('users/');
return this.assessmentsRef;
}
UpdateAssessments (business: Business){
this.assessmentRef.update({
busiName: business.busiName
});
}
DeleteAssessment(){
this.assessmentRef = this.db.object('users/');
this.assessmentRef.remove();
}
商业.ts
export interface Business {
$key: string;
busiName: string;
}
解决方案
现在你正在用这个创建数据:
const key = this.database.ref('/users').push().key;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
当您调用Firebase 时,会生成一个新的唯一位置,该位置是以JSONpush()
开头的键。-M...
该值不是当前用户的 UID,因此这些规则不允许用户读取或写入它:
"users": {
"$uid": {
".write": "$uid === auth.uid";
".read": "$uid === auth.uid";
}
}
相反,您应该使用用户的 UID 作为键将数据写入节点下。那看起来像:
const key = this.database.ref('/users').push().key;
if (firebase.auth().currentUser) {
const key = firebase.auth().currentUser.uid;
this.database.ref('/users').child(key).set({
busiName: business.busiName
});
}
else {
console.error("No current user while trying to write business name");
}
推荐阅读
- math - 如何获取.net DrawArc 方法的弧长
- excel - 具有可变行数的 VBA Sum 列
- angular - 在哪里存储 ElectronJS 应用程序的敏感数据?
- c++ - 如何在 Makefile 中链接 boost 库?
- excel - 如果下拉列表中的条件与表中的数据匹配,则粘贴行:如果包含下拉列表的单元格留空,则跳过部分代码
- javascript - 当我使用 webpack 并将其导入应用程序 js 时,滑动滑块不起作用
- python - 在python中将Timex字符串转换为日期时间
- windows - 如何在 GetAdaptersAddresses 结果中识别“无线托管网络”
- bixby - bixby 中模棱两可的话语的后备意图
- android - Android 上的 Flutter 编译错误:找不到 com.android.support:support-v4:27.0.3