ブログサービスの管理機能と一般機能の違い

記事
IT・テクノロジー

ブログサービスの管理機能と一般機能の違い

Firebase のストレージからファイルの一覧を取得する機能について考える場合、管理機能として利用する場合と、一般の利用者が利用する場合では作り方を変えた方が良い場合があります。この記事では、機能の実装のポイントについて利用者の立場で考えた例を紹介します。


同じ機能でも色々ある実装方法

プログラミングでは、同じ機能でもその実現方法(実装方法)は一つではなく、いくつかの方法がある場合が殆どです。その場合どの実現方法が一番いいのか迷う場合も多いと思います。

難しいのは、同じ機能でもベストな方法は同じでは無い場合が多く何を基準に選んだら良いか迷ってしまう点にあるかと思います。今回は、Firebase のストレージとデータベース(Cloud Firestore)を利用してブログサービスを作成した場合について考えてみます。 その中でも、Firebase のストレージに保存されているファイルの一覧を表示する機能について検討した例を紹介します。

前提として、ブログの記事を、Firebase のストレージにアップロードして、その記事を Web ブラウザで表示するようなサービスを考えます。ブログサービスの基本機能については既に概要を紹介しているので基本的な仕組みについてはそちらをご覧ください。この記事でもファイルの一覧表示について紹介しています。別の記事では、Firebase のストレージに保存しているファイル情報を Firegbase のデータベースにも保存して、通常はそちらからデータを取得する用法を紹介しています。

以前の記事で紹介していますが、Firebase のストレージがサポートしているファイル(フォルダ)の一覧を取得する方法は大きく二つのやり方があります。

1. フォルダ内の全てのファイル(フォルダ)を取得する方法
2. フォルダ内のファイルの中から指定した数のファイル(フォルダ)を取得する方法
です。

一般の利用者向けには二番目の指定した数のファイル(フォルダ)を取得する方法を採用しました。 これにはいくつか理由があって、

* フォルダ内のファイルの数が多い場合、データの取得に時間がかかる
* フォルダ内のファイルの数が多い場合、表示するスペースが大きくなってしまう
特にスマホなどでサイトを、見る場合を考えると画面が PC に比べると小さなスマホでは、ディスプレー上に表示できるファイルの数は限られています。ファイルのリストが多い場合縦に長いページになるためスクロールしてファイルを探すのは使いづらい部分があります。むしろ、画面に収まる数を表示してページを捲るようにした方が使いやすい場合が多くなります。

データの取得は実際には精々数秒から数十秒程度の差ですが、予めファイルの情報のサマリーをデータベースに置いてある置くと、表示にかかる時間を短縮できるので、利用者から見るとサイトの動き(反応)が速くなったように感じます。

管理機能の場合はどうか?

では、同じように Firebase のストレージに保存されているブログの記事の一覧を管理目的で表示させる場合を考えてみます。

管理機能を利用する場合、Web ページの表示にかかる時間はそれほど問題ない場合が殆どです。それよりは効率的に管理をやりやすい方が助かります。例えば、ファイルをまとめて消去したり移動したり、あるいはまとめてダウンロードしたい場合などは、ファイルをページに分けて表示するよりは多少時間がかかっても、全部のファイルをまとめて表示させた方が便利な場合が多くなります。

実際に、管理操作やブログの記事の執筆はスマホよりは PC で行った方が効率が良く便利です。また PC の場合は画面もスマホよりは大きくスクロールした場合の表示もリストが長い場合でもそれほど不便には感じません。もちろん、人によってスマホやタブレットで原稿を作成する方もいらっしゃると思うので一概には決められませんが、少なくても私の場合は、このように考えるわけです。

そうすると、必然的に作り方(実現・実装方法)も変わってきます。

今回は、「私自身がサイトの管理を行う」と言う視点で考えると

* 表示に時間がかかってもフォルダ内の全てのファイルを表示
* まとめて操作が可能にする(削除や移動など)
* Firebase のストレージの「生データ」を表示させたい
と言うのがポイントになります。

当然ですが、先日紹介した一般の人が使うブログを表示するための機能の作り方とは変わってきます。

利用する Firebase ストレージの API は?

今回は、全てのファイル(フォルダ)を表示させるので利用する API は「listAll()」と言う API を利用します。 前回は、指定した数のファイル(フォルダ)を表示させるために、「list()」を使いました。 当然ですが、受け渡しするデータ(インターフェース)も変わってきます。

実は、全部一度で表示してしまう方がシンプルです。

export function listAllFiles(path: string): Promise<StorageList | undefined> {
  return new Promise((resolve) => {
    const storageRef: firebase.storage.Reference = firebase
      .storage()
      .ref()
      .child(path);
    storageRef
      .listAll()
      .then((res) => {
        const folderRefs: Array<firebase.storage.Reference> = res.prefixes;
        const itemRefs: Array<firebase.storage.Reference> = res.items;
        const storageList: StorageList = {
          folders: folderRefs,
          files: itemRefs,
        };
        resolve(storageList);
      })
      .catch((error: any) => {
        resolve(undefined);
      });
  });
}
指定した数のファイル(フォルダ)を表示する場合には、次のページの情報を別に保存したり、前のページに戻るための仕組みを作る必要があるので少し面倒になります。 (*)これについては、別の記事で紹介予定です

いずれの場合も、フォルダを階層に沿って降りていく場合、上の階層に戻るような操作が必要になります。

フォルダの階層の移動のための処理には、「スタック」を使います。スタックはデータ構造の一つで、データを積み上げて行くようにデータを保存します。データを取り出す際は、一番上(最後に積み上げたデータ)を取り出すと言う方法で行います。Javascript(Typescript)では、「array」に標準でサポートされている関数(push/pop)を使います。データを積み上げる時には、「push」を、データを取り出す場合には「pop」を使います。

これで、ファイルのパス(path)の階層をスタック(_pathStack_)に入れて管理します。

function folderSelectionEvent(
    athsStack:Array<string>,
    folder: firebase.storage.Reference
) {
    pathStack.push(folder.name);
    path = folder.name;
    listAllFiles(getPath(pathStack)).then((result) => {
        if (result) {
            folders = result.folders;
            files = result.files;
        }
    });
}
function getPath(pathStack: Array<string>) {
    let newPath = "";
    for (let i = 0; i < pathStack.length; i++) {
        if (pathStack[i] !== "") {
          newPath = newPath + "/" + pathStack[i];
        }
    }
    return newPath;
}
function moveUpperFolder(pathStack) {
    const upperFolder = pathStack.pop();
    if (upperFolder) {
        this.path = upperFolder;
        const fullPath = getPath(pathStack);
        listAllFiles(fullPath).then((result) => {
          if (result) {
            folders = result.folders;
            files = result.files;
          }
        });
      }
}

ポイントは利用する人は誰か?

今回は、「私がサイトの管理者」と言う前提で考えてみました。 ポイントは、シンプルで「誰が使うのか」を一番で考える事です。当然ですが、私以外の人が管理者の場合にはまた違った実装の方が良いという場合もあります。

* 使う人は誰か?
* 使う人はどの様に使うか?
* 使う人にとって何が便利か?使いやすいか?
を考える必要があります。

ところが!?

今回は、私自身なので「何が欲しいか」は自分の事なので良くわかります。従って自分の事を考えれば良いのでシンプルです。ところが、これが他の人だったらどうでしょうか?

親しい人やよく知っている人ならばある程度「想像」「推測」をすることができます。しかし、あくまで「想像」や「推測」に過ぎません。大切なのは、きちんと「コミュニケーション」をして、相手の欲しいものを出来るだけ汲み取ることにあります。これが実に難しい事で「何が欲しいの?」と聞いて本当に欲しいものがわかる場合はほとんどありません。いろいろな情報や希望、困っていることを集めて「相手の欲しいものに辿り着く」という形で探すことになります。これが、「コミュニケーション」をしてと表現した理由です。ただ「聞く」だけでは、なかなか「本当に求められているもの」に辿り着けないものです。

まとめ
ブログサービスに限らず、Web サービスや Web アプリを作成する場合に必要な機能は、それを利用する利用者(お客様)の事をよく考えて実装する必要があります。プログラムの実装は、いろいろなやり方があるのが普通でどれを選んで、どの様な組み合わせで作るかは開発者(エンジニア)が決めることになります。

しかし、同じような機能でも、利用者によって微妙に使い方や、使うための(スマホか PC などのような)環境も違います。開発者が「考える・思う」やり方はあくまで開発者の視点であって、実際に使う人にとっては違うことも沢山あります。プログラマとして経験を積むといろいろなやり方を思いつくようになりますが、どれをどの様に使うかは、「使う人」第一で考えることがとても大切です。

今回は、Firebase のストレージに保存されているブログの記事の一覧の表示というシンプルな例を取り上げましたが、こんなシンプルな事でも色々実装方法が変わってきます。

プログラムの開発には、開発者、発注元、利用者のコミュニケーションが重要でこれが上手く行くと良いプログラムが作れます。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す