AngularJs ✕ Firebaseで爆速イメージストア環境の作成

  • 7
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

以前、AngularJs ✕ Firebaseで爆速リアルタイムアプリケーションの作成という記事を書きましたが、
今回は画像をさくっとどこかにあげて利用したい時、firebaseを使えば、5分で環境が出来ます。

S3、Parseの利用を検討しましたが、

  • 無料
  • APIドキュメントがわかりやすい(Parseはファイルストレージが20GBだが、ドキュメントがわかりにくい)
  • リアルタイムにデータ同期しやすい

上記の点でAngularJs×Firebaseを採用。なんといってもリアルタイムデータ同期が魅力的。

※Milkcocoaは検討してませんw

Firebaseとは

いわゆるモバイルBassでWebアプリケーション、モバイル・アプリケーションの開発者向けにリアルタイムにスケーラブルなバックエンドサービスを提供しています。
一定の転送量、接続数、容量は無料で、クレジットなしで使用できます。

ストレージ1GBまで無料なので、まぁ問題ないレベル。
バックアップは無料プランでは取れません。
https://www.firebase.com/

AngularFire

そして、AngularJsからFirebaseを利用できる、
AngularFireというAPIも公開されていますので、
バックエンドのコードを書く必要も、サーバも必要なく、
必要な作業に集中できます。

AngularFireのAPIを利用することで、
Angularjsのモデルが自動的に同期され、Firebase上でリアルタイムにデータバインディングされます。
これでhtml側でのview, Angularjsでのmodel, firebaseでストアされたjsonのデータの3wayデータバインディングが可能となります。

angular-file-upload

FlashによるFileAPI代替を提供するモジュール
HTML5のFileAPIを利用,HTML5のFileAPIサポートしていないブラウザ(IE8、IE9など)にはFlashを利用して同等の機能を提供。
今回はbase64データのURL生成してアップロードしています。

サンプル:画像アップロードアプリ

index.html
<script src="https://gist.github.com/manchan/0d8597b1ac131d1b1f16.js"></script>
<noscript><pre><code>

File: index.html
-------------------------



<!doctype html>
<html>
<head>
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.3.0/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.1.3/angularfire.min.js"></script>
<!-- Angular-file-upload -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/danialfarid-angular-file-upload/10.1.0/ng-file-upload.js"></script>
<style type="text/css">
    .thumb {width: 24px;height: 24px;float: none;position: relative;top: 7px;}
    form .progress {line-height: 15px;}
    .progress {display: inline-block;width: 100px;border: 3px groove #CCC;}
    .progress div {font-size: smaller;background: orange;width: 0;}
    ol, ul{list-style:none;}
    #content #photo{position: relative;overflow: hidden;}
    #content #photo ul{position: relative;left: 50%;float: left;}
    #content #photo li{position: relative;left: -50%;float: left;}
    #content #photo .r20{margin-left:20px;}
    #content #photo li img {width: 420px;height: 420px;}
</style>
</head>
<body>
<div>
    <h1>AngularJs practice</h1>
    <body ng-app="fileUpload" ng-controller="MyCtrl">
    <form name="myForm">
        <fieldset>
            <legend>Upload on form submit</legend>
            Title:
            <input type="text" name="userName" ng-model="username" size="31" required>
            <i ng-show="myForm.userName.$error.required">*required</i>
            <br>Photo:
            <input type="file" ngf-select ng-model="picFile" name="file"
                   accept="image/*" ngf-max-size="2MB" required>
            <i ng-show="myForm.file.$error.required">*required</i><br>
            <i ng-show="myForm.file.$error.maxSize">File too large 
          {{picFile.size / 1000000|number:1}}MB: max {{picFile.$errorParam}}</i>
                    <img ng-show="myForm.file.$valid" ngf-thumbnail="picFile" class="thumb"> <button ng-click="picFile = null" ng-show="picFile">Remove</button>
            <br>
            <button ng-disabled="!myForm.$valid"
                    ng-click="uploadPic(picFile)">Submit</button>
            <span ng-show="picFile.result">Upload Successful</span>
            <span class="err" ng-show="errorMsg">{{errorMsg}}</span>
        </fieldset>
        <br>
    </form>
    <div id="content">
        <h2>photo</h2>
        <div id="photo">
            <button type="button" class="btn btn-danger" ng-click="image_all_remove()">All Remove</button>
            <ul>
                <li ng-repeat="img in images | orderBy:'-submitDate'">
                    <p>{{img.$key}}:{{img.submitDate}}</p>
                    <img src="{{img.images}}" alt="" width="{{img.width}}" height="{{img.height}}"/>
                </li>
            </ul>
        </div>
    </div>
    </body>
    <script type="text/javascript">
    // 依存モジュールとしてfirebase、ngFileUploadを登録   
    var app = angular.module('fileUpload', ['ngFileUpload', 'firebase']);
    app.controller('MyCtrl', ['$scope','$firebase','$firebaseArray', 'Upload', '$timeout', function ($scope,$firebase, $firebaseArray, Upload, $timeout) {

        // "https://<your-firebase>.firebaseio.com/"
        var fb = new Firebase("https://<your-firebase>.firebaseio.com/");
        var ref = fb.child("images").orderByChild("submitDate");        
        var sync = $firebaseArray(ref);
        var syncArray = $firebaseArray(fb.child("images"));
        // ストアされたjson objectをmodelにバインド
        $scope.images = sync
        $scope.uploadPic = function(file) {
            var title = $scope.username;
            var submitDate = new Date().toISOString();
            var images =  Upload.base64DataUrl(file).then(function(base64Urls){

                  $timeout(function () {
                    file.result = base64Urls.data;
                  });

                // 同期配列にArray.push
                syncArray.$add({
                    title:     title,
                    images : base64Urls,
                    submitDate: submitDate
                })
                .then(function(error) {
                    if (error) {
                            console.log("Error:",error);
                        } else {
                            console.log("Post set successfully!");
                        }
                    });
            });
        };
        // 画像全削除
        $scope.image_all_remove = function(){
            angular.forEach($scope.images, function(img, i){
                var row = $scope.images.$getRecord($scope.images[i].$id);
                $scope.images.$remove(row);
            });
        };
    }]);    
    </script>
</div>
</body>
</html>

</code></pre></noscript>

わずか110行で簡単イメージストアアプリが作成できます。
var ref = new Firebase("https://<your-firebase>.firebaseio.com/");

上記の箇所をfirebaseにサインアップして、URLを書き換えるだけですぐ使えます。
サインアップはこちらから
https://www.firebase.com/login/

※注意

無料プランでストレージは1GBまでです。

Firebaseにストアされたデータにindexをはる方法

設定で、json形式でkey,rulesの中に.indexOnを記述するだけ
詳細はこちら
https://www.firebase.com/docs/security/guide/indexing-data.html

Firebaseにストアされたデータのセキュリティに関して

jsonでのセキュリティルールの設定が可能。
認証されたユーザがどのようにデータを変更できるかを決める。
データの転送はSSL経由。

さらなる詳細はこちら
https://www.firebase.com/docs/security/

AngularFireの使用アプリ

好きなアーティストの音楽をランキング順の聴くことができるサービスです。
Recentの箇所をfirebaseでストアしています。
Lamusica
http://manchan.github.io/lamusica/
githubはこちら
https://github.com/manchan/lamusica

AngularFireのドキュメントはこちら

https://www.firebase.com/docs/web/libraries/angular/index.html

ng-file-uploadのドキュメントはこちら

https://github.com/danialfarid/ng-file-upload

おわりに

5分は長すぎたかもしれません。