tamuraです。
Googleスプレッドシートで忘年会の景品のリクエストを受け付けていたのですが、スマートフォンからだと入力がしにくいようで、なかなか集まりません。 Firebaseを使ってHTMLでリクエスト受け付けるものを作ってみました。
プロジェクト作成まで
右上のコンソールへ移動を押します。
新規プロジェクトを作成します。
プロジェクト名と国/地域を入力します。
できました。
気になる料金ですが、左下にプランが出ているのでそれでわかります。 今は Spark という Free プランです
データベースの作成
メニューから Database を選択します。
既存のセキュリティルールではユーザの認証が必要です
とでるので、認証が必要ない状態にしてしまいます。 ルールというタブを開くと読み書きに関する設定が出てきます。
これを true に変えてやることで誰でも読み書きできるようになります。
セキュリティルールが公開対象として定義されているため、誰でもデータベースの読み取りや書き込みを行えます とありますが、上等です。
HTMLの作成
Overview画面から
ウェブアプリにFirebaseを追加
を押すとJavaScriptが出てきます。
この初期値が入ったJavaScriptを使います。
データベースの使い方
基本的にドキュメントを見るとわかりやすく書いてあります。(日本語で!) https://firebase.google.com/docs/database/web/start
var database = firebase.database();
これでデータベースを使えるようになります。
書き込み
今回は追記なので追記のやり方について書きます。 (追記以外は本家のドキュメントを見てください。日本語でわかりやすく書いてあります!)
https://firebase.google.com/docs/database/web/save-datavar newPostKey = database.ref().child('items').push().key,
updates = {};
updates['items/' + newPostKey] = {
name: '宝くじ10枚',
price: '3000'
};
database.ref().update(updates);
まず、push()
を使ってデータのリストに追加します。
key
で追加したデータの一意なIDを取得します。
updates
いうオブジェクトに今取得したIDを使ってデータをセットします。
updates['items/' + newPostKey] = {
name: '宝くじ10枚',
price: '3000'
};
これは
updates = {
'items/' + newPostKey: {
name: '宝くじ10枚',
price: '3000'
}
}
と同じ(なはず)です。
ほかにセットしたいデータがあればこのタイミングでオブジェクトに突っ込んでおけます。
最後に、update()
でデータを一気に更新します。
すばらしい。
読み込み
これも非常にわかりやすいドキュメントが用意されています。 今回は追加しかないので簡単です。
https://firebase.google.com/docs/database/web/retrieve-data
database.ref('items').on('child_added', function (snapshot) {
var item = snapshot.val();
$('#items').append(item.name + ':' + item.price);
});
これで追加されたタイミングで自動で更新してくれます。 最初にアクセスしたときもちゃんと反応してデータを取得してくれます。
便利。
ホスティング
作ったらデプロイです。 Firebaseはホスティングもやってくれます。SSLです。
npm install -g firebase-tools
npm login
npm init
npm deploy
でFirebaseにデプロイできます。 node.jsを入れていない人はこのタイミングで入れると良いです。
カスタムドメイン
CNAMEを使うことでカスタムドメインを使うことができます。 その際に、 Authentication の ログイン方法 タブにある OAuthリダイレクトドメイン に運用する予定のカスタムドメインを追加しておかないとデータの読み書きができなくなります。ご注意。
まとめ
できあがったソースはこんな感じです。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>忘年会景品アンケート</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container-fluid">
<h2>忘年会景品アンケート</h2>
<div>
<input id="name" placeholder="商品名(必須)" required><br>
<input id="price" placeholder="値段"><br>
<input id="url" type="url" placeholder="商品URL(あれば)"><br>
<textarea id="message" placeholder="あついコメント(必須)" required></textarea>
<br>
<button id="send">投稿</button>
</div>
<br>
<table id="items" class="table table-striped table-bordered">
<tr>
<th>商品名</th>
<th>値段</th>
<th>商品URL</th>
<th>あついコメント</th>
</tr>
</table>
</div>
<script src="https://www.gstatic.com/firebasejs/3.5.0/firebase.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
(function(window, $, firebase, undefined) {
var database;
function pushItem(postData) {
var newPostKey = database.ref().child('items').push().key,
updates = {};
updates['items/' + newPostKey] = postData;
return database.ref().update(updates);
}
function validate(name, price, url, message) {
return name && message;
}
function updateView(name, price, url, message) {
var $name = '<td>' + name + '</td>',
$price = '<td>' + (price ? price : '<br>') + '</td>',
$url = '<td>' + (url ? '<a href="' + url + '">商品URL</a>' : '<br>') + '</td>',
$message = '<td>' + message.replace(/\r?\n/g, '<br>') + '</td>';
$('#items').append('<tr>' + $name + $price + $url + $message + '</tr>');
}
function init () {
var config = {
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxxxxxxx.firebaseapp.com",
databaseURL: "https://xxxxxxxxxxxxxx.firebaseio.com",
storageBucket: "xxxxxxxxxxxxxxxx.appspot.com",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
};
firebase.initializeApp(config);
database = firebase.database();
$('#send').click(function () {
var name = $('#name').val(),
price = $('#price').val(),
url = $('#url').val(),
message = $('#message').val(),
postData = {
name: name,
price: price,
url: url,
message: message
};
if (validate(name, price, url, message)) {
pushItem(postData);
$('#name').val('');
$('#price').val('');
$('#url').val('');
$('#message').val('');
}
});
database.ref('items').on('child_added', function (snapshot) {
var item = snapshot.val();
updateView(item.name, item.price, item.url, item.message);
});
}
window.anketo = {
version: '0.0.1',
init: init
};
})(window, $, firebase);
window.anketo.init();
</script>
</body>
</html>