LoginSignup
1
0

More than 3 years have passed since last update.

AngularでCloud Storage for Firebaseにファイルアップロード(キャッシュとか権限とか)

Last updated at Posted at 2019-11-25

記事の目的

Firebase便利ですよね。
なかでも簡単にファイルアップロードは便利です。

こちらに手順を記載されている記事があります
https://qiita.com/daikiojm/items/1c5940d618b3b644439a

  • downloadUrlが非推奨になっていること
  • キャッシュの設定とか
  • 権限を少し

の追記だけしておきます。

早速コードの箇所だけ

Material Designを利用していますが、使わなくても大丈夫です。
(ボタンをおしゃれにするために、inputフィールドを隠しています。)

<!-- テキストファイルを選択するinput -->
<div id="input-area">
  <input #fileUpload hidden type="file" value=""
         (change)="selectFile($event)"/>
  <button
      (click)="fileUpload.click()"
      type="button"
      mat-button color="primary">ファイル選択
  </button>
  <p *ngIf="selectedFile">アップロードファイル: {{selectedFile.name}}</p>
  <button [disabled]="!selectedFile"
          mat-stroked-button color="primary"
          (click)="upload();">Upload
  </button>
</div>

<!-- アップロードしたファイルを表示するエリア -->
<a *ngIf="uploadFileUrl" [href]="uploadFileUrl">{{ uploadFileUrl }}</a>

  // selected file
  public selectedFile;

  // ファイルのURL
  public uploadFileUrl;

  constructor(
    private storage: AngularFireStorage,
    private store: AngularFirestore,
  ) {
  }

  selectFile(evt: any) {
    // ファイルを未選択で閉じた場合など。
    if (!evt.target || !evt.target.files || evt.target.files.length !== 1) {
      this.selectedFile = null;
      return;
    }
    this.selectedFile = evt.target.files[0];
  }

  async upload() {
    if (!this.selectedFile) {
      return;
    }

    // ファイルをUIDごとに分けるとか
    const filePath = 'uploads/' + 'uid等でフォルダを分ける' + '/' + this.selectedFile.name;

    // ストレージの参照をもつ
    const storageRef = this.storage.ref(filePath);

    // putまたはputStringであげる
    const result = await storageRef.put(this.selectedFile, {'cacheControl': 'public, max-age=86400'});
    console.log(result);

    // storageの参照からダウンロードURLを取得(先の例にあったようにobservableのまま受け取ってもOK)
    storageRef.getDownloadURL().subscribe((result) => {
      this.uploadFileUrl = result;
      // ここでStoreにユーザがアップロードしたファイル一覧に保持とか
    });
  }

ほぼ同じ方法で
blobやbase64もできます。
https://firebase.google.com/docs/storage/web/upload-files?hl=ja

    const result = await storageRef.put(this.selectedFile, {'cacheControl': 'public, max-age=86400'});

ここで例えばキャッシュをもたせる場合は、
上記のように、putのオプションとして設定可能です。

FirebaseStorageの権限について

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read;
    }
    match /uploads/{allPaths=**} {
        allow read;
        allow create: if request.auth != null && request.resource.size <= 10 * 1024 * 1024;
        allow update: if request.auth.uid == resource.data.uid && request.resource.size <= 10 * 1024 * 1024;
        allow delete: if request.auth.uid == resource.data.uid;
    }
  }
}

    match /{allPaths=**} {
      allow read;
    }

最初に任意のパスへの書き込みは規制した方が良いかと思います。

    match /uploads/{allPaths=**} {
        allow read;
        allow create: if request.auth != null && request.resource.size <= 10 * 1024 * 1024;
        allow update: if request.auth.uid == resource.data.uid && request.resource.size <= 10 * 1024 * 1024;
        allow delete: if request.auth.uid == resource.data.uid;
    }

続いて、uploads配下(ここは利用したいパスによります)に関しての権限を決めます。
例として、プロフィール画像のアップロードの場合、

  • read: 読み込みは誰でもOK → if はなければ常にTrue扱い
  • create: 認証済みユーザなら登録可なので、request.authがnullじゃないこと=認証済みユーザであること を確認(firebase authenticationを利用して下さい)
  • update: データを登録したユーザと変更者のUIDが一致していたら変更可とする(firebase authenticationを利用して下さい)
  • delete: データを登録したユーザと削除者のUIDが一致していたら削除可とする(firebase authenticationを利用して下さい)

追加で、createとuploadの際に10MB以下としてあります。
(大きいファイルをがんがん上げられるのを防ぐため)

雑ですいません。

Angular最高!!

詳細は以下に有ります。

https://github.com/angular/angularfire/blob/master/docs/storage/storage.md
あと使いそうなところだと

    // observe percentage changes
    this.uploadPercent = task.percentageChanges();
    // get notified when the download URL is available
    task.snapshotChanges().pipe(
        finalize(() => this.downloadURL = fileRef.getDownloadURL() )
     )
    .subscribe()

ここの箇所でUpload時のプログラスバーを出したいときなど便利です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0