LoginSignup
7
7

More than 5 years have passed since last update.

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

Posted at

以前、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のドキュメントはこちら

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

おわりに

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

7
7
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
7
7