Пользователь AUTHENTICATED, но: появляется ошибка «Firebase Storage: у пользователя нет прав доступа к« пути » - PullRequest
0 голосов
/ 17 ноября 2018

Я уже внедрил аутентификацию в своем приложении, и у меня нет проблем с созданием пользователя и аутентификацией. Однако сейчас я пытаюсь загрузить файл в Firebase Storage, но он будет работать толькокогда я удаляю правило авторизации и делаю доступ открытым.Если я оставляю правила по умолчанию, чтобы разрешить доступ только аутентифицированным пользователям (что я и хочу), я получаю сообщение об ошибке: Firebase Storage: User does not have permission to access 'profile-image/test.PNG'. Я вызвал метод для проверки моего состояния авторизации прямо перед запросом put, и я могу читать / писатьк базе данных пожарного магазина без проблем, так что я точно знаю, что аутентифицирован.

Я полный FNG, поэтому есть большая вероятность, что проблема в том, что я сделал / не сделал что-то глупое.Я использую Angular, если это актуально.Я также активировал платежный аккаунт в Google Cloud Platform, но это не имело значения.

Вот мой консольный журнал, показывающий ссылку, которую я использовал, файл, который я пытаюсь добавить (который опять-таки оба прекрасно работают, когда я делаю доступ открытым), мой uid из вызова состояния auth, итогда ошибка:

STARTING UPLOAD SERVICE                        upload.service.ts:26
FIREBASE STORAGE REFERENCE:                    upload.service.ts:27 
Reference {authWrapper: AuthWrapper, location: Location}
  authWrapper: AuthWrapper {bucket_: "my-app.appspot.com", deleted_: false, app_: FirebaseAppImpl, storageRefMaker_: ƒ, requestMaker_: ƒ, …}
bucket: (...)
fullPath: (...)
location: Location {bucket: "my-app.appspot.com", path_: "profile-image/test.PNG"}
name: (...)
parent: (...)
root: (...)
storage: (...)
__proto__: Object
                                                 upload.service.ts:28 
FILE CONTENTS:
                                                 upload.service.ts:29 
File(286831) {name: "test.PNG", lastModified: 1542480795011, lastModifiedDate: Sat Nov 17 2018 13:53:15 GMT-0500 (Eastern Standard Time), webkitRelativePath: "", size: 286831, …}
                                                 upload.service.ts:24 
USER AUTHENTICATED: Er6sWsDvEjM69WBAKxQffcbdPZG2
POST https://firebasestorage.googleapis.com/v0/b/{my-app-name}/o?name=profile-image%2Ftest.PNG 403
                                                 upload.service.ts:33  
FirebaseStorageError {code_: "storage/unauthorized", message_: "Firebase Storage: User does not have permission to access 'profile-image/test.PNG'.", 
serverResponse_: "{↵  "error": {↵    "code": 403,↵    "message": "Pe…n denied. Could not perform this operation"↵  }↵}", name_: "FirebaseError"}
code: (...)
code_: "storage/unauthorized"
message: (...)
message_: "Firebase Storage: User does not have permission to access 'profile-image/test.PNG'."
name: (...)
name_: "FirebaseError"
serverResponse: (...)
serverResponse_: "{↵  "error": {↵    "code": 403,↵    "message": "Permission denied. Could not perform this operation"↵  }↵}"
__proto__: Object 

Правила хранения Firebase

service firebase.storage {
 match /b/my-app.appspot.com/o {
  match /{allPaths=**} {
   allow read, write: if request.auth != null;
  }
 }
}  

(я также пробовал request.auth.uid! = null, но это не имело значения.)

Моя служба загрузки:

import { Injectable } from '@angular/core';
import * as firebase from 'firebase/app';
import 'firebase/storage';
import { AuthService } from '../services/auth.service';


@Injectable({
  providedIn: 'root'
})
export class UploadService {

  constructor(
    private authService: AuthService
  ) { }

  pushUpload(uploadFile: File) {
    console.log("STARTING UPLOAD SERVICE")
    var storage = firebase.storage();
    var storageRef = storage.ref();
    var profileRef = storageRef.child('profile-image');
    var docRef = profileRef.child(uploadFile.name);

    this.authService.getAuthState().subscribe(auth => {
      console.log("USER AUTHENTICATED: " + auth.uid);
    })
    console.log("FIREBASE STORAGE REFERENCE:")
    console.log(docRef);
    console.log("FILE CONTENTS:");
    console.log(uploadFile);
    docRef.put(uploadFile).then(res => {
      console.log(res);
    }).catch(err => {
      console.log(err);
    });
  }
}

Конфигурация Firebase в environment.ts:

import * as fb from 'firebase/app';

// This file can be replaced during build by using the `fileReplacements` array.
// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.

export const environment = {
  production: false,
  firebase: {
    apiKey: "{my-api-key}",
    authDomain: "my-app.firebaseapp.com",
    databaseURL: "my-app.firebaseio.com",
    projectId: "my-app",
    storageBucket: "gs://my-app.appspot.com",
    messagingSenderId: "####"
  }
};

fb.initializeApp(environment.firebase);

Я заменил некоторую идентифицирующую информацию на общую в файле log & environment.ts консоли,Я должен также упомянуть, что до того, как я добавил fb.initializeApp(environment.firebase);, аутентификация работала у меня просто отлично, но я получал ошибку без этой строки, когда пытался сделать запрос на загрузку.

Большое спасибо заранее за любые советы, которые вы можете получить, и, если я предоставлю больше информации, пожалуйста, дайте мне знать!

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Как оказалось, имело значение, что я использовал Angular.Мне нужно было добавить AngularFireStorage к моему app.module.ts следующим образом:

import { AngularFireStorage } from '@angular/fire/storage'; 

@NgModule({
....
providers: [..., AngularFireStorage]

, а затем также пришлось импортировать в мои uploads.component.ts:

import { AngularFireStorage, AngularFireUploadTask } from '@angular/fire/storage';

, а затем яполностью удалил мой UploadService и зацепил части учебника этого парня: https://angularfirebase.com/lessons/firebase-storage-with-angularfire-dropzone-file-uploader/, который использует AngularFireUploadTask и некоторые Observables, чтобы действительно легко выполнить весь процесс загрузки.Итак, вот результирующий метод, который я использовал в файле uploads.component.ts:

import { Component, OnInit, Input } from '@angular/core';
import { AngularFireStorage, AngularFireUploadTask } from '@angular/fire/storage';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-uploads',
  templateUrl: './uploads.component.html',
  styleUrls: ['./uploads.component.css']
})
export class UploadsComponent implements OnInit {
  @Input() uploadFolder: string;  //the folder to save this particular upload to in the Storage Bucket   
  selectedFile: File;
  task: AngularFireUploadTask;  // Main task 
  percentage: Observable<number>;  // Progress monitoring
  snapshot: Observable<any>;// Progress monitoring


  constructor(
    private storage: AngularFireStorage
    ) { }

  ngOnInit() {}

  .
  .
  .

  startUpload() {  
    if (this.selectedFile.type.split('/')[0] !== 'image') { 
      console.error('unsupported file type :( ')
      return;
    } else {
      const path = this.uploadFolder + "/" + this.userID;
      // The main task
      this.task = this.storage.upload(path, this.selectedFile)
      // Progress monitoring
      this.percentage = this.task.percentageChanges();
      this.percentage.subscribe(data => {
        // Do something with my progress
      })
      this.snapshot = this.task.snapshotChanges();
      this.snapshot.subscribe(data => {
        // Do something with my progress
      })
      // The file's download URL
      this.task.then(snapshot => {
        console.log("UPLOAD SUCCESS!");
        snapshot.ref.getDownloadURL().then(url => {
          console.log(url);
          //Do something with my new file's url
        })
      }, 
      (err) => {
        //Do something about errors...  
      });
    }
  }
}

И я удалил инициализацию firebase из моего файла environment.ts, так что Angular явно инициализирует для меня firebase где-то с этого момента.не нужноЯ полагаю, что именно поэтому было расхождение между тем, почему Firestore показывал, что я проходил аутентификацию (потому что я инициализировал firebase для входа в систему и firestore через AngularFire), но Firebase Storage показал, что я НЕ проходил аутентификацию (потому что я инициализировал firebase для THAT отдельно в моем environment.ts файл, который был моим обходным путем, чтобы не использовать AngularFireStorage, как я должен был).Так что в основном все сводится к тому, что я (не) полностью не понял, что именно Angular делал для меня.тьфу ... я действительно надеюсь, что это поможет кому-то в какой-то момент ...

0 голосов
/ 18 ноября 2018

allow read, write: if request.auth != null;

означает, что вы должны войти в систему, прежде чем сможете писать туда.

просто попробуйте один раз с ==, и вы увидите, что это работает.

...