Thursday, December 6, 2018

[Vue] VueFire – Firebase Auth and RTDB


 Vue.js   Firebase   VueFire



Introduction


VueFire is the official vue.js package for Google Firebase.
We will learn how to login/logout add use Realtime Database Bindings.




Environment


Vue.js 2.5.11
Vue CLI 3.2.1
Firebase Javascript SDK 5.5.8
VueFire 1.4.5


Firebase


Firebase setup
Assume that you had created a Realtime Database in Firebase, import the following JSON to your RTDB Data and set the Rules.


Data

{
  "Demo" : {
    "products" : {
      "3a30b4b6-8fe5-48cf-9aab-06f431257928" : {
        "id" : "3a30b4b6-8fe5-48cf-9aab-06f431257928",
        "price" : "2500",
        "title" : "Implementing Domain-Driven Design",
        "type" : "Book",
        "typeId" : "1"
      },
      "6cfd8b64-0ff2-4bde-8278-befaa2f4e42f" : {
        "id" : "6cfd8b64-0ff2-4bde-8278-befaa2f4e42f",
        "price" : "500",
        "title" : "Toy Robot",
        "type" : "Toy",
        "typeId" : "2"
      },
      "800afd3c-1615-49ba-b33d-497842af6c82" : {
        "id" : "800afd3c-1615-49ba-b33d-497842af6c82",
        "price" : "1000",
        "title" : "Star Wars",
        "type" : "Book",
        "typeId" : "1"
      },
      "fa7ece70-6f5c-41a2-a7a6-cd03ca3d0136" : {
        "id" : "fa7ece70-6f5c-41a2-a7a6-cd03ca3d0136",
        "price" : "800",
        "title" : "Essential Scrum",
        "type" : "Book",
        "typeId" : "1"
      }
    }
  }
}


Rules

{
  "rules": {
    "Demo":
        {
        "products":{
          ".read": "auth != null"
        }
      }
    }
}



Implement


Install

$ npm install firebase
$ npm install vuefire


Import and Register

import VueFire from 'vuefire'

/* firebase */
// import * as firebase from 'firebase' //Dev mode
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'

//firebase
const firebaseConfig = {
    apiKey: "xxxxxx",
    authDomain: "xxxx.firebaseapp.com",
    databaseURL: "https://xxxx.com",
    projectId: "xxxxx",
    storageBucket: "xxxxx",
    messagingSenderId: "xxxxx"
};

const firebaseApp = firebase.initializeApp(firebaseConfig);
window.firebase = firebase;
window.firebaseDb = firebaseApp.database();
window.firebaseAuth = firebaseApp.auth();

Vue.use(VueFire)


Login/Logout

Here is the sample code for login with Google provider.

<template>
  <div class="card">
    <div class="card-block">
        <div class="card-text">
            <div v-if="!isAuth" class="text-center">

                <div class="container">
                    <div class="row">
                        <div class="col-md-6">
                            <button class="btn btn-toolbar" @click="login('google')">
                                <img width="30" src="../assets/images/google-logo.png" />
                                Use Google Account
                            </button>
                        </div>
                    </div>
                </div>
            </div>
            <div v-else class="text-center">
                <table class="table">
                    <tr>
                        <td class="text-center">
                            <label class="control-label">{{ user.displayName }}</label>
                        </td>
                    </tr>
                    <tr>
                        <td class="text-center">
                            <img :src="user.photoURL" width="100px" height="100px"/>
                        </td>
                    </tr>
                    <tr>
                            <td class="text-center">
                                Phone number: <label class="control-label">{{ user.phoenNumber || '(no phone number)'}}</label>
                            </td>
                        </tr>
                    <tr>
                        <td class="text-center">
                            Email: <label class="control-label">{{ user.email || '(no email)'}}</label>
                        </td>
                    </tr>                
                </table>
                <div>
                    <input type="button" class="btn btn-warning" @click="logout" value="Logout" />
                </div>
            </div>
        </div>
    </div>
  </div>
</template>

<script>

export default {
  name: "login",
  data() {
    return {
      user: null,
      isAuth: false //Is authorized flag
    };
  },
  methods: {
    login(providerName) {
      let provider = null;
      switch (providerName) {
        case "google":
          provider = new firebase.auth.GoogleAuthProvider();
          break;
      }

      firebaseAuth.signInWithPopup(provider)
        .then(result => {
          this.user = result.user;

        }).catch(err => console.error(err));
    },

    logout() {
      firebaseAuth.signOut()
        .then(() => {
          this.user = null;
          this.isAuth = false;
        }).catch(err => console.log(error));
    }
  },
  beforeCreate(){
      firebaseAuth.onAuthStateChanged((user) => {
        if (user) {
          this.user = user;
          this.isAuth = true;
        }
      })
  },
  created() {
      console.log(firebaseDb);
      console.log(firebaseAuth);
  }
};
</script>

Demo





Array/Object bindings

JS

new Vue({
    el: "#app",
    firebase: {
      fbArray: firebaseDb.ref('Demo/products').limitToLast(10), //bind as an array
      fbObject: {
        source: firebaseDb.ref('Demo/products/800afd3c-1615-49ba-b33d-497842af6c82'),
        asObject: true, //Bind as object
        cancelCallback: function () { },
        readyCallback: function () { }
    }
  }
});


Html (For showing fbArray and fbObject)

<pre>{{ fbObject }}</pre>
<table class="table">
<thead class="thead-dark">
    <tr>
    <th>Type</th>
    <th>ID</th>
    <th>Title</th>
    <th>Price</th>
    </tr>
</thead>
<tbody>
    <tr v-for="item in fbArray" :key="item.id">
    <td>{{ item.type }}</td>
    <td>{{ item.id }}</td>
    <td>{{ item.title }}</td>
    <td>{{ item.price }}</td>
    </tr>
</tbody>
</table>


The above Html will results in



Reference







Sunday, December 2, 2018

Agile Tour Taipei 2018 會後心得




這次是我第三次參加Agile Tour Taipei,今年參加了以下session

1.  從乙方PM的角度看敏捷 – KC Liu
2.  Scrum遇上Pattern – Teddy Chen
3.  Workshop: 利用顧客旅程地圖檢視服務體驗 葉致宏

快速分享一下部分心得


從乙方PM的角度看敏捷

KC老師透過實務上擔任專案經理的經驗,來描述如何將敏捷的做法實踐於大型專案。



上圖是專案降低失敗風險的方式,如果您也是Project Manager的話,應該不用多說,做專案什麼鳥事都會發生; 當然每個專案風險管理的方式不同,在A專案適用的方法,不一定就可以套用在B專案。




「敏捷是PM的救命丹嗎?」
只有無限的預算和資源才是吧(笑)

我個人是很推崇Agile的,但是以專案經理的角度來看,我不認為所有的專案或團隊都適合立即完全跑敏捷的方式(要配合天時地利人和阿!),但是iteration的開發方式是很有價值的,可以拉近USER溝通和減少領域知識的落差。



由於很多企業在前年已完成預算編列,傳統專案通常會簽Fixed Price(固定價款),也就是期望在固定的成本和時程中完成雙方確認的很模糊範疇; 但是這種簽約方式很不利於擁抱改變的敏捷方式。 因此PM需要思考如何在傳統合約加入敏捷友善的條款; 例如要求對方Key user/Stakeholder必須出席例會、以固定幾個Sprint作為Milestone的付款條件。

PS. 對於敏捷式合約的類型若有興趣,可參考PMI ACPDomain 2 提到的Agile Contract Types (Reference: Domain 2. Value-driven Delivery)





Workshop: 利用顧客旅程地圖檢視服務體驗

顧客旅程地圖(User Journey Map)UX其中一個定性研究(Qualitative research)的方法。
致宏老師先透過影片的方式介紹顧客旅程地圖。 這個影片主要是去記錄一位去診所掛號看醫生的病人,在求診的過程中是否有遇到非預期的情況,例如不曉得下一步要做什麼,或是等候但不知道還要等多久;目的在於理解使用者的UX

而在Workshop我們是以上次去咖啡館的過程,從過程(故事)中的動詞挑選出:

l  活動:目的
l  互動:過程以達成目的
l 
l 
l  境:地點
l  情緒(感受)


例如 「打開手機APP查詢每日咖啡優惠代碼,以Line Pay支付金額」這個過程可拆解為:

活動
查詢咖啡優惠代碼
支付
互動
打開手機APP
打開Line Pay
自己
自己
店員
手機
手機
卡機
咖啡館
咖啡館
情緒
J
J

我們小組建立的User Journey Map如下圖,可以看出使用者在哪一個步驟的UX是不好的。



接下來利用以下方式,將User Journey Map整理成在每一個步驟所需要的資源或方法:


名詞
對應
描述
1
物理證據
人、物

2
顧客行為
活動

3
前台服務
互動

4
後台服務

使用者無法直接看到,但我們需要提供的服務
5
內部支援

由我們內部即可直接提供的服務或資源
6
外部支援

需由外部協助提供的服務或資源

其中 1~3 是使用者可實際看到的服務。

例如以上述User Journey Map例子:「打開手機APP查詢每日咖啡優惠代碼,以Line Pay支付金額」可整理如下:

物理證據
自己
手機
自己
店員
手機
卡機
顧客行為
查詢咖啡優惠代碼
支付
前台服務
打開手機APP
打開Line Pay

後台服務
APP開發
咖啡優惠管理
整合Line Pay
POS過帳
內部支援
咖啡優惠行銷
帳務系統
外部支援
外包廠商開發APP
Line Pay整合
卡機及POS整合

針對使用者UX不好的地方,可在此步驟思考及計畫如何優化?需要那些內外部資源?

最後我們小組整理如下:




以上是這次參與Agile Tour Taipei的一些記錄,明年再見!