#1.Firebaseの利用開始
とりあえずここから新規登録してね
※Googleアカウントが必要だよ
https://console.firebase.google.com/
##新規プロジェクトを作成
ログインできたら、「新規プロジェクトを作成」ボタンから
新規プロジェクトを作ろう
※国はまぁ、日本人なんで日本選ぼう
これでプロジェクトできたね!早いね!
#2.デプロイしてみよう
##Firebase toolsをインストールしよう
npmでFirebase toolsをインストール
npmがない人はnode.jsをインストールしてね。
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
brew install nodebrew
nodebrew install-binary latest
npm install -g firebase-tools
##コードを書くためのディレクトリを用意しよう
適当なディレクトリを作ったら、コマンドラインでそこに移動して
以下のコマンドを打ってください。
firebase login
そしたらなんかブラウザが起動するのでFirebaseの登録に使った
Googleアカウントでブラウザからログインしてください
次に以下のコマンドを打ってください
firebase init
色々聞かれるので
What Firebase CLI features do you want to setup for this folder?
→これはそのままEnter
Project Setup
→さっき作ったFirebaseプロジェクトを選択
Database Setup
→これはそのままEnter
What do you want to use as your public directory?
→これはyを選択しEnter
Configure as a single-page app (rewrite all urls to /index.html)?
→これもyを選択しEnter
これで色々ファイルが勝手に作成されました!
public
└index.html
database.rules.json
firebase.json
publicフォルダの下に作られたindex.htmlを適当にいじってください。
とりあえずh1タグの中身かえるとか。
そしてデプロイコマンドを叩けば、デプロイ完了です。
firebase deploy
このコマンドを叩くと、太字でHosting URLという項目が表示されます。
このURLが今デプロイしたサイトのURLになります。
アクセスしてみよう。
#3.データベースを使ってみよう
Consoleの「Database」ってとこをクリックしてみよう。
まだ何もないね!
##セキュリティルールを解放しろ!
「既定のセキュリティ ルールではユーザーの認証が必要です」って青文字が出てます。
このままだとユーザー認証とかしないとデータベースが使えないんですね。
なので「ルール」ってタブをクリックしてくださいね。
そしたら以下のような感じになってるのがわかりますね。
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
これを
{
"rules": {
".read": true,
".write": true
}
}
こうしちゃおう
そして「公開」ボタンを押せば・・・
「セキュリティ ルールが公開対象として定義されているため、誰でもデータベースの読み取りや書き込みを行えます」
みたいなのが赤文字で出てきましたね。
これでユーザー認証なしでDBが使えるようになってしまいました!
※ここのルールと「database.rules.json」で定義したルールは、プロジェクトのデプロイ時に同期されます。
「database.rules.json」の内容で上書きされるので注意が必要です。
というか実際は「database.rules.json」を正として開発するのが正しいですね。
##コードを書こう
publicディレクトリ内のindex.htmlを以下の内容に書き換えてください。
※jQueryを使用しています。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Firebase Study</title>
<style media="screen">
</style>
</head>
<body>
<form id="input_form">
<input type="text" id="name" size="10" placeholder="Name" value="名無し">
<input type="text" id="input_text" size="50">
<button type="submit" id="send_btn">SEND</button>
<hr>
<div id="chat_area"></div>
</form>
</body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
$(function(){
// ↓↓↓ここの情報を自分のプロジェクトのものに置き換えてください
// Initialize Firebase
var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
// ↑↑↑ここの情報を自分のプロジェクトのものに置き換えてください
firebase.initializeApp(config);
// submit時
$("#input_form").submit(function(){
writeChatData($("#name").val(), $("#input_text").val());
return false;
});
// 発言を登録
function writeChatData(name, text) {
$("#input_text").val("");
firebase.database().ref('chat').push({
name: name,
text: text
});
}
// 発言を表示
firebase.database().ref("chat").on("value", function(snapshot) {
$("#chat_area").html("");
var logs = snapshot.val();
for (var key in logs) {
var logHtml = '<p>' + logs[key].name + ':' + logs[key].text + '</p><hr>'
$("#chat_area").prepend(logHtml);
}
});
});
</script>
</html>
configを自分のプロジェクトの設定に変更してください。
ダッシュボードを開き、トップの右側にある「ウェブアプリにFirebaseを追加」のアイコンをクリックすると、そのプロジェクトのconfigが表示されます。
##実行しよう
以下のコマンドを打つと、ローカルでサーバーが起動します。
firebase serve
localhost:5000にアクセスすると、作成したチャット画面が表示されます。
#4.認証機能を使おう
##まずはダッシュボードでAuthenticationの設定
「Authentication」メニューをクリックし、「ログイン方法」タブを選択してください。
「メール/パスワード」が無効になっていると思いますので、
有効にして保存してください。
##コードを変更
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Firebase Study</title>
<style media="screen">
/** ↓↓4.認証で追加↓↓ */
body {
margin: 0;
padding: 0;
}
header {
background: #f99;
padding: 10px;
text-align: right;
}
#input_form {
padding: 10px;
}
/** ↑↑4.認証で追加↑↑ */
</style>
</head>
<body>
<!-- ↓↓4.認証で追加↓↓ -->
<header>
<div id="login_info">
<input type="email" id="email" placeholder="email">
<input type="password" id="password" placeholder="password">
<button id="login_btn">ログイン</button>
<button id="user_regist_btn">新規登録</button>
</div>
<div id="logout_info" style="display: none;">
<button id="logout_btn">ログアウト</button>
</div>
</header>
<!-- ↑↑4.認証で追加↑↑ -->
<form id="input_form">
<input type="text" id="name" size="10" placeholder="Name" value="名無し">
<input type="text" id="input_text" size="50">
<button type="submit" id="send_btn">SEND</button>
<hr>
<div id="chat_area"></div>
</form>
</body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
$(function(){
// ↓↓↓ここの情報を自分のプロジェクトのものに置き換えてください
// Initialize Firebase
var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
// ↑↑↑ここの情報を自分のプロジェクトのものに置き換えてください
firebase.initializeApp(config);
// submit時
$("#input_form").submit(function(){
writeChatData($("#name").val(), $("#input_text").val());
return false;
});
// 発言を登録
function writeChatData(name, text) {
$("#input_text").val("");
firebase.database().ref('chat').push({
name: name,
text: text
});
}
// 発言を表示
firebase.database().ref("chat").on("value", function(snapshot) {
$("#chat_area").html("");
var logs = snapshot.val();
for (var key in logs) {
var logHtml = '<p>' + logs[key].name + ':' + logs[key].text + '</p><hr>'
$("#chat_area").prepend(logHtml);
}
});
//↓↓4.認証で追加↓↓
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$("#login_info").hide();
$("#logout_info").show();
if (user.displayName) {
$("#name").val(user.displayName);
}
} else {
$("#logout_info").hide();
$("#login_info").show();
$("#name").val("");
}
});
// ユーザー登録
$("#user_regist_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログイン
$("#login_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログアウト
$("#logout_btn").click(function(){
firebase.auth().signOut().then(function() {
// Sign-out successful.
}, function(error) {
// An error happened.
});
});
// 名前が変更されたらプロフィールを変更
$("#name").change(function(){
var user = firebase.auth().currentUser;
if (user) {
user.updateProfile({
displayName: $("#name").val()
});
}
});
//↑↑4.認証で追加↑↑
});
</script>
</html>
##GoogleやFacebookアカウントで認証したい
ここまでわかればあとはドキュメント見れば大丈夫
https://firebase.google.com/docs/auth/web/google-signin
https://firebase.google.com/docs/auth/web/facebook-login
#5.セキュリティルールを設定しよう
せっかくログイン機能作ったけど、誰でも書き込めるしあんま意味ないよね。
なのでセキュリティルールを設定してみましょう
##ログインしてないと書き込み禁止にする
database.rules.jsonをいじろう
{
"rules": {
".read": true,
".write": "auth != null"
}
}
エラーをわかりやすくするためindex.htmlもちょこっとだけいじる
※発言を登録するメソッドにcatchの部分を追加
// 発言を登録
function writeChatData(name, text) {
$("#input_text").val("");
firebase.database().ref('chat').push({
name: name,
text: text
}).catch(function(error) {
alert(error.message);
});
}
そしたらデプロイ
firebase deploy
ログインしないと書き込めなくなりましたね
##もっと難しいルールを
自分の発言だけを変更可能にする
{
"rules": {
"chat": {
".read": true,
"$message": {
".write": "data.child('user_id').val() == auth.uid || !data.exists()"
}
}
}
}
dataは変更前のデータを表します。
authはログインユーザーの情報を表しています。
$messageはchat要素の子供の要素を表しています。
$につづく名前はなんでもいいです。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Firebase Study</title>
<style media="screen">
/** ↓↓4.認証で追加↓↓ */
body {
margin: 0;
padding: 0;
}
header {
background: #f99;
padding: 10px;
text-align: right;
}
#input_form {
padding: 10px;
}
</style>
</head>
<body>
<!-- ↓↓4.認証で追加↓↓ -->
<header>
<div id="login_info">
<input type="email" id="email" placeholder="email">
<input type="password" id="password" placeholder="password">
<button id="login_btn">ログイン</button>
<button id="user_regist_btn">新規登録</button>
</div>
<div id="logout_info" style="display: none;">
<button id="logout_btn">ログアウト</button>
</div>
</header>
<!-- ↑↑4.認証で追加↑↑ -->
<form id="input_form">
<input type="text" id="name" size="10" placeholder="Name" value="名無し">
<input type="text" id="input_text" size="50">
<button type="submit" id="send_btn">SEND</button>
<hr>
<div id="chat_area"></div>
</form>
</body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
$(function(){
// ↓↓↓ここの情報を自分のプロジェクトのものに置き換えてください
// Initialize Firebase
var config = {
apiKey: '<your-api-key>',
authDomain: '<your-auth-domain>',
databaseURL: '<your-database-url>',
storageBucket: '<your-storage-bucket>'
};
// ↑↑↑ここの情報を自分のプロジェクトのものに置き換えてください
firebase.initializeApp(config);
var userId = "";
// submit時
$("#input_form").submit(function(){
writeChatData($("#name").val(), $("#input_text").val());
return false;
});
// 発言を登録
function writeChatData(name, text) {
$("#input_text").val("");
firebase.database().ref('chat').push({
name: name,
text: text,
user_id: userId // ←5.セキュリティルールで変更
}).catch(function(error) {
alert(error.message);
});
}
//↓↓5.セキュリティルールで変更↓↓
// 発言を更新
function updateChatData(key, text) {
firebase.database().ref('chat/' + key + '/text').set(text).catch(function(error) {
alert(error.message);
});
}
//↑↑5.セキュリティルールで変更↑↑
// 発言を表示
firebase.database().ref("chat").on("value", function(snapshot) {
$("#chat_area").html("");
var logs = snapshot.val();
for (var key in logs) {
var logHtml = '';
//↓↓5.セキュリティルールで変更↓↓
if (logs[key].user_id == userId) {
logHtml = '<p>' + logs[key].name + ':<input type="text" class="update_text" size="50" value="' + logs[key].text + '" data-key="' + key + '"/></p><hr>'
} else {
logHtml = '<p>' + logs[key].name + ':' + logs[key].text + '</p><hr>'
}
//↑↑5.セキュリティルールで変更↑↑
$("#chat_area").prepend(logHtml);
}
//↓↓5.セキュリティルールで変更↓↓
$(".update_text").off("change");
$(".update_text").on("change", function(){
var key = $(this).attr("data-key");
var text = $(this).val();
updateChatData(key, text);
});
//↑↑5.セキュリティルールで変更↑↑
});
//↓↓4.認証で追加↓↓
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$("#login_info").hide();
$("#logout_info").show();
if (user.displayName) {
$("#name").val(user.displayName);
}
userId = user.uid;
} else {
$("#logout_info").hide();
$("#login_info").show();
$("#name").val("");
}
});
// ユーザー登録
$("#user_regist_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログイン
$("#login_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログアウト
$("#logout_btn").click(function(){
firebase.auth().signOut().then(function() {
// Sign-out successful.
}, function(error) {
// An error happened.
});
});
// 名前が変更されたらプロフィールを変更
$("#name").change(function(){
var user = firebase.auth().currentUser;
if (user) {
user.updateProfile({
displayName: $("#name").val()
});
}
});
//↑↑4.認証で追加↑↑
});
</script>
</html>
#6.ストレージを使おう
FirebaseからGCPのGoogle Cloud Storageを使うことができます。
こんな感じで書けばファイルをアップロードできます
var storageRef = firebase.storage().ref();
var uploadTask = storageRef.child('images/' + userId + '/' + file.name).put(file);
ログインしたユーザーのアイコン画像をアップロードして
発言と一緒にアイコンも表示されるようにしてみよう
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Firebase Study</title>
<style media="screen">
/** ↓↓4.認証で追加↓↓ */
body {
margin: 0;
padding: 0;
}
header {
background: #f99;
padding: 10px;
text-align: right;
}
#input_form {
padding: 10px;
}
#user_icon {
height: 60px;
}
</style>
</head>
<body>
<!-- ↓↓4.認証で追加↓↓ -->
<header>
<div id="login_info">
<input type="email" id="email" placeholder="email">
<input type="password" id="password" placeholder="password">
<button id="login_btn">ログイン</button>
<button id="user_regist_btn">新規登録</button>
</div>
<div id="logout_info" style="display: none;">
<!-- ↓↓6.ストレージで追加↓↓ -->
<input type="file" id="icon_file"><button id="icon_up_btn">アイコン画像をアップロード</button>
<!-- ↑↑6.ストレージで追加↑↑ -->
<button id="logout_btn">ログアウト</button>
</div>
</header>
<!-- ↑↑4.認証で追加↑↑ -->
<form id="input_form">
<!-- ↓↓6.ストレージで追加↓↓ -->
<img src="" id="user_icon">
<!-- ↑↑6.ストレージで追加↑↑ -->
<input type="text" id="name" size="10" placeholder="Name" value="名無し">
<input type="text" id="input_text" size="50">
<button type="submit" id="send_btn">SEND</button>
<hr>
<div id="chat_area"></div>
</form>
</body>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://www.gstatic.com/firebasejs/3.6.1/firebase.js"></script>
<script>
$(function(){
// ↓↓↓ここの情報を自分のプロジェクトのものに置き換えてください
// Initialize Firebase
var config = {
apiKey: "AIzaSyDFWFBb2ZsPoN3q7Y-KnOp_xboLvBPmK-Q",
authDomain: "fb-hack-fa53d.firebaseapp.com",
databaseURL: "https://fb-hack-fa53d.firebaseio.com",
storageBucket: "fb-hack-fa53d.appspot.com",
messagingSenderId: "462609738357"
};
// ↑↑↑ここの情報を自分のプロジェクトのものに置き換えてください
firebase.initializeApp(config);
var userId = "";
// submit時
$("#input_form").submit(function(){
writeChatData($("#name").val(), $("#input_text").val());
return false;
});
// 発言を登録
function writeChatData(name, text) {
$("#input_text").val("");
firebase.database().ref('chat').push({
name: name,
text: text,
user_id: userId, // ←5.セキュリティルールで変更
photo_url: $("#user_icon").attr("src") // ←6.ストレージで変更
}).catch(function(error) {
alert(error.message);
});
}
//↓↓5.セキュリティルールで変更↓↓
// 発言を更新
function updateChatData(key, text) {
firebase.database().ref('chat/' + key + '/text').set(text).catch(function(error) {
alert(error.message);
});
}
//↑↑5.セキュリティルールで変更↑↑
// 発言を表示
firebase.database().ref("chat").on("value", function(snapshot) {
$("#chat_area").html("");
var logs = snapshot.val();
for (var key in logs) {
var logHtml = '';
//↓↓5.セキュリティルールで変更↓↓
var photoUrl = logs[key].photo_url; // 6.ストレージで変更
if (!photoUrl) photoUrl = ""; // 6.ストレージで変更
if (logs[key].user_id == userId) {
// 6.ストレージで変更
logHtml = '<p><img src="' + photoUrl + '" height="40px">' + logs[key].name + ':<input type="text" class="update_text" size="50" value="' + logs[key].text + '" data-key="' + key + '"/></p><hr>'
} else {
// 6.ストレージで変更
logHtml = '<p><img src="' + photoUrl + '" height="40px">' + logs[key].name + ':' + logs[key].text + '</p><hr>'
}
//↑↑5.セキュリティルールで変更↑↑
$("#chat_area").prepend(logHtml);
}
//↓↓5.セキュリティルールで変更↓↓
$(".update_text").off("change");
$(".update_text").on("change", function(){
var key = $(this).attr("data-key");
var text = $(this).val();
updateChatData(key, text);
});
//↑↑5.セキュリティルールで変更↑↑
});
//↓↓4.認証で追加↓↓
firebase.auth().onAuthStateChanged(function(user) {
if (user) {
$("#login_info").hide();
$("#logout_info").show();
if (user.displayName) {
$("#name").val(user.displayName);
}
//↓↓6.ストレージで追加↓↓
if (user.photoURL) {
$("#user_icon").attr("src", user.photoURL);
}
//↑↑6.ストレージで追加↑↑
userId = user.uid;
} else {
$("#logout_info").hide();
$("#login_info").show();
$("#name").val("");
}
});
// ユーザー登録
$("#user_regist_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログイン
$("#login_btn").click(function(){
var email = $("#email").val();
var password = $("#password").val();
firebase.auth().signInWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
alert(errorMessage);
});
});
// ログアウト
$("#logout_btn").click(function(){
firebase.auth().signOut().then(function() {
// Sign-out successful.
}, function(error) {
// An error happened.
});
});
// 名前が変更されたらプロフィールを変更
$("#name").change(function(){
var user = firebase.auth().currentUser;
if (user) {
user.updateProfile({
displayName: $("#name").val()
});
}
});
//↑↑4.認証で追加↑↑
//↓↓6.ストレージで追加↓↓
$("#icon_up_btn").click(function(){
var file = $('#icon_file')[0].files[0];
if (!file) return false;
var storageRef = firebase.storage().ref();
var uploadTask = storageRef.child('images/' + userId + '/' + file.name).put(file);
uploadTask.on('state_changed', function(snapshot){
// アップロード中のステータスが変わったときに何かする場所
}, function(error) {
alert("アップロードに失敗しました");
}, function() {
var iconURL = uploadTask.snapshot.downloadURL;
console.log(iconURL);
$('#icon_file').val("");
alert("アップロード完了");
// ユーザーのアイコン画像に設定
var user = firebase.auth().currentUser;
if (user) {
user.updateProfile({
photoURL: iconURL
});
}
$("#user_icon").attr("src", iconURL);
});
});
//↑↑6.ストレージで追加↑↑
});
</script>
</html>
とりあえず以上です。
お疲れ様でした。