顯示具有 firebase 標籤的文章。 顯示所有文章
顯示具有 firebase 標籤的文章。 顯示所有文章

Android與FireBase(五)google登入功能實作

延續上一篇的FaceBook登入功能
身為Google底下的FireBase
當然也可以輕易實現Google帳號的登入!


本部份需要完成兩大部份
1.FireBase給予App的授權、2.主程式撰寫

Integrating Google Sign-In into Your Android App

1.新增SHA-1認證(SHA是一種憑證、類似實做FB登入時的hash key、詳細原理可見維基

1.1 以官方提供的憑證產生方式,在Android Studio內的終端機,輸入:

keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore



(此為示範,請於網站內,複製自己系統的指令)

1.2 此時會要求輸入讀取金鑰的密碼,預設是"android"鍵盤輸入時不會跳出字
輸入完畢後,按下Enter,即會顯示結果



1.3 此處因密鑰長度關係(詳細原因仍須進一步查證),複製MD5,作為SHA-1的憑證

2. 來到FireBase的OverView,選擇連結的程式右上角,進入"設定"



2.1 來到最下方,"新增指紋",將1.1的MD5碼貼上,新增為SHA-1


以上完成第一部份的FireBase給予憑證
接著便可以來到Android Studio,撰寫App的登入功能

Authenticate Using Google Sign-In on Android

參考自官方說明整合說明,我們需要依序加入套件、新增UI、撰寫功能

1.1 到build.gradle內,加入以下參考:
compile 'com.google.firebase:firebase-auth:11.4.2'
compile 'com.google.android.gms:play-services-auth:11.4.2'

如果先前做過Email登入、FB登入功能,就無須額外加"firebase-auth"的套件了
唯一要注意"play-services-auth"版本,與原先套件版本有無衝突。

1.2 到layout.xml檔案內,新增google的signIn按鈕



2. 撰寫程式碼(大部分參考自官方說明

2.1 以GoogleSignInOptions與GoogleApiClient物件
來連結登入API與儲存登入帳號資訊的物件
(注意:RC_SIGN_IN 的數值須自行宣告,否則執行API時會報錯找不到)



2.2 我們新增一個專門設定2.1物件的函式googleConfig(),在onCreate()狀態呼叫設定


在登入按鈕設定listener,呼應signIn()方法
同時signIn()將導向google提供的登入頁,回傳結果

2.3 覆寫onActivityResult()來接收2.2回傳結果,交給handleSignInResult()來處理




2.4 延續2.3,handleSignInResult()判斷是否登入成功,成功的話,即傳送帳戶物件
給firebaseAuthWithGoogle(),完成向firebase註冊新的使用者,同時執行updateUI()
(updateUI()參考,可見上一篇Android與FireBase(四)


3. 在onCreate()內呼叫googleConfig(),點擊登入時,便會依序合作完成功能:
googleConfig()->signIn()->onActivityResult()->handleSignInResult()->firebaseAuthWithGoogle()

編譯安裝成功後,便可以看到google的登入按鈕,點擊後可以選擇登入帳號
登入完會顯示帳號名稱、Email

 


同時firebase網站內的Authentication,也會新增此使用者囉!



到本篇為止,我們已經學會使用大部分的社群帳戶Provider,
FaceBook跟Google直接作為登入帳號,已經綽綽有餘了。
至於Twitter我就不多介紹了,可以自行探討,
而GitHub則是比較偏向開發者的社群,一般應用上使用客群較少。



接著將會再探討FireBase的其他功能實作!
而各大網站也有豐富相關教學,都值得大家互相學習研究!


Android與FireBase(四)FB登入功能實作

在完成Email登入後
發現註冊並沒有經過審核!(即用戶使用非法email也可以註冊登入)
當然我們可以自己寫個驗證信功能

但那太複雜了,而且需要在後端實現,使用者體驗也會降低

當今各大社群ˋ影音等多媒體網站,
早就改榜定TwitterˋFBˋgoogle帳號
用戶只需要"一鍵"就能搞定註冊 / 登入

而且使用各Provider的帳戶授權
安全性、資訊、便利性都大大提高
省去自己維護紀錄,開發又快速,何樂而不為~


以下我們將完成三大部份:
FB授權、FireBase授權、主程式撰寫

FB開發者請求連結

1.前往FB開發者的網站(需要用個人FB登入)

1.1 建立應用程式:
  - 輸入你想連的App名稱
     - 網站會自動連結你FB的信箱填入

1.2 跳過不須安裝

1.3 連結 Facebook SDK 
  - SDK選擇"Maven"(Maven功能不多做解釋,有興趣可另行搜尋)
        - 在專案的build.gradle檔案,加入repositories {mavenCentral()}
        - 在dependencies{}加入compile 'com.facebook.android:facebook-login:[4,5)'


1.4 編輯您的 Manifest
  - 在app/src/main/res/values/strings.xml內,加入facebook_app_id跟scheme


  - 在Manifest.xml內,加入<uses-permission android:name="android.permission.INTERNET"/>
  給予連線網路能力
  - 在 application標籤下,加入meta-data 跟FB的activity(必須加在MainActivity前!!!)


1.5 將應用程式與您的套件名稱和預設類別建立連結
  -套件名稱,參考其格式,可以在Manifest的package找到
  -activity同理,套件後加上MainActivity


1.6 提供您應用程式的「開發金鑰雜湊」和「發行金鑰雜湊」
  -在Andriod Studio內找到Terminal終端機視窗
  -輸入 keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 - binary | openssl base64 

   便會產生一串金鑰,複製貼上於網頁中即可。
  (如果出現問題,根據系統建議,安裝缺少的套件工具,再試一次即可)

1.7 可跳過

1.8 新增「Facebook 登入」按鈕
  -在main_layout.xml的UI檔案內,找個地方加入LoginButton元件(FB提供的登入按鈕)

至此我們可以歸納,以個人權限,告訴FB說我們想要一個App程式,需要登入
然後在App專案內,連結了SDK套件,設定了FB給的App Id,也告訴FB我們的key,
最後新增按鈕。

接著要在FireBase內開啟FB登入功能,並輸入登入功能的code!

FireBase授權連結


1.先在FB開發網站內選擇剛新增的程式,可以看到連結的App Id 跟金鑰


2.來到FireBase內,選擇Authentication->登入方式->facebook->啟用

3.把步驟1的Id跟金鑰輸入後,複製 OAuth 重新導向 URI 




4.把步驟3的URI,貼到步驟1網站->FaceBook登入->設定->OAuth 重新導向 URI->儲存


如此便完成了FireBase與FB程式與App的連結

主程式撰寫

最後當然是在App內寫入我們要的登入頁面
參考FireBase提供的官方方法
前置1~5步驟,我們都已設定好了,只需要直接進入coding

1-1.我們另外宣告一個faceBookLogin()的方法,把第一段中
 // Initialize Facebook Login button程式碼貼入
(此段功能:找到UI元件,並宣告callBack物件,取得登入成功或失敗結果)
  (記得要在onCreate()時呼叫此函式,才會運行)
(handleFacebookAccessToken方法,在步驟4才會寫到)


1-2.複製貼上protected void onActivityResult(int requestCode, int resultCode, Intent data) 方法

2.在onCreate內,貼上
private FirebaseAuth mAuth;
mAuth = FirebaseAuth.getInstance();
3.複製貼上public void onStart()方法

4.複製貼上private void handleFacebookAccessToken(AccessToken token)方法,
 此函式提供登入成功/失敗後,回傳結果的處理方式(步驟1-1函式會呼叫到)。

5.updateUI(null); 方法要自己寫,看是更新元件、顯示文字訊息、或跳轉都可以
(以下為參考,登入後取得user,顯示姓名與Email)



以上,我們便完成了所有步驟! 可以用FB登入囉~
畫面上即會顯示出登入者的FB姓名跟Email!
FireBase內也會新增使用者喔!

 


至於使用者的判別,可以用uid,其餘相關功能
可在其他相關網站有所說明。
而此App登入後,就會記住使用者的授權了(因為onStart與onCreate已做紀錄)
想要登出時,只要呼叫 FirebaseAuth.getInstance().signOut();

之後我們再探討google帳號的登入功能吧!




------------------------------------------------------------------------------------------------------------------

1.如果遇到 loginButton無法運作時
在onCreate加入FacebookSdk.sdkInitialize方法即可解決

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FacebookSdk.sdkInitialize(getApplicationContext());    setContentView(R.layout.activity_main);}

2.如果遇到app hash key不符時
這是因為裝置上的FB App產生的bug
只要在FB developer的網站內,設定加入動態產生的hash key就好

private void _hashKey(){
    try {
        PackageInfo info = getPackageManager().getPackageInfo(
                "com.firebase.naylor.g2bfirst",                PackageManager.GET_SIGNATURES);
  for (Signature signature : info.signatures) {
            MessageDigest md = MessageDigest.getInstance("SHA");         
   md.update(signature.toByteArray());           
   Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));        }
    } catch (PackageManager.NameNotFoundException e) {

    } catch (NoSuchAlgorithmException e) {

    }
}

在logcat搜尋KeyHash,複製貼上到FB developer的程式設定內即可。
(這些code是動態產生hash key,發生bug時,會與上頭在終端機輸入指令
產生不同hash key,而此時須以動態產生的為主!) 參考解決來源

Android與FireBase(三)RecyclerView

延續「綠豆湯」Hank老師的實作:
https://litotom.com/2016/11/25/as_222_firebase_db_2/


為何要使用RecyclerView?

可參考以下說明:http://julianchu.net/2016/03/13-recyclerview.html


簡單來說,ListView在資料更新中
不斷刷新List的View元件,是浪費系統資源的行為,
過大的List資料,將會產生肥大的ListView


而Recycler顧名思義


就是它能夠回收利用View,只抽換資料就好,
而要實現此UI,需要以下幾個步驟:

1.繼承RecyclerView.Adapter類別,實現自己的Adapter類別
2.繼承RecyclerView.ViewHolder類別,在Adapter類別下,實現自己的ViewHolder類別
3.承步驟1,覆寫
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {}
@Override
public void onBindViewHolder(ViewHolder holder, int position){}
@Override
public int getItemCount() {}
4.宣告Adapter類別物件,設定給RecyclerViewUI物件


其中需要注意的是:



※JavaBean類別,可用右鍵->Generate->自動產生Gettrt、Setter方法
※adapter.notifyDataSetChanged();
的方法用來通知UI改變資料,請放在list.add行為之後,
否則會發生資料為空的問題(源自asynchronously 非同步的問題)
※public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType)
方法下,context可進一步用來取得LayoutInflater物件,運行inflate方法



現有Android可搜尋的教學資源相當豐富,如有侵權請告知,當立即下架。

Android與FireBase(二)Authentication-Email登入實作

使用FireBase開發APP

以登入功能為例
其實在Android Studio內->Tool->FireBase->Authentication
早已詳列每個步驟、每個功能應注意事項
甚至提供API使用的範例程式碼
對於物件、方法理解上,真是相當貼心!

今天討論FireBase的登入功能,本文參考自:
https://litotom.com/2016/11/21/as_222_firebase_email/

設定好可登入帳戶後,即可使用
(雖然帳戶沒有審核,可以用非法帳號,
但是來到忘記密碼、收信時,使用者便會出問題囉!)

一樣我們在MainActivity.java內,寫一個方法
新增一個設定/取得帳戶的物、以及設定一個監聽器


Activity的生命週期

本方法應在onCreate()中呼叫,進行設定
隨後在onStart()中,加入:
auth.addAuthStateListener(authStateListener);
開始進行監聽,監聽器被加入後,即開啟功能

發現使用者未登入,進入LoginActivity頁面
(要注意的是REQUEST_LOGIN,是需要自行定義/宣告的常數數值)
此處以startActivityForResult導入頁面,是為了取得登入成功與否結果,
關於頁面切換方法有二:startActivityForResult、startActivity
介紹可參考此網頁:
http://hatsukiakio.blogspot.tw/2009/06/startactivitystartactivityforresult.html

當我們順利來到LoginActivity頁面時
只要用"登入按鈕",讓輸入的帳號密碼經FireBase判斷是否正確
正確的話,以
setResult(RESULT_OK);finish();
此頁面便會回傳RESULT_OK訊息回到MainActivity
然後關閉,按鈕觸發方法步驟如下


入門者需注意:LoginActivity頁面的xml設計,
輸入欄位元件需要使用android.support.design.widget.TextInputLayout類別
xml內元件如下:

同時記得在build.gradle內的dependencies
加入compile 'com.android.support:design:26.+'(版本26,依開發版本而定)

有了介面跟以上code便能仰賴google強大的後端,擁有會員登入系統囉!!






Android與FireBase(一)DataBase-資料存取

首先,必須先知道

FireBase是什麼(https://tw.alphacamp.co/2016/07/22/firebase/)


Google強大地整合了開發人員

入門時最容易遇到的問題 : 資料庫! 
以及委外的認證機制 + 使用者分析 + 錯誤報告 +
儲存空間 + 推播通知 + 廣告 + 伺服器運行程式...
相當完整地提供了"後台"的功能!!!
有了以上功能的"後台",讓開發人員可以~
相當快速地建構專案,省去架設伺服器、資料庫...等等繁複的前置步驟
(APP、Web本就是相當薄的UI層,所有應用的發展,都少不了那個雲端!)


那麼該怎麼快速上手呢?



此處可以參考:
https://litotom.com/2016/05/20/2016-firebase/

其中MainActivity的介面設計,寫入以下程式碼時
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
會產生找不到@dimen的問題
此處錯誤是因為找不到此資源檔
所以請在res->values->new file->dimention
產生dimention.xml後,寫入
<resources>    
<dimen name="activity_horizontal_margin">16dp</dimen>    
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
便能順利找到檔案


接著因目前Android更新至2.3.3,所以從FireBase設定開始,按以下施工:
https://litotom.com/2016/11/19/as_222_firebase_db/

到此為止,便能順利連結到所設定的FireBase。
---------------------------------------------------------

如何取出資料?

建議將連結頁面物件(listView)
與連結DataBase分為兩個涵式
1.findViews(),用來設定連結頁面元件
2.setDBdata(),用來取得資料存入ArrayAdapter物件
再一併於onCreate()內執行:
public class MainActivity extends AppCompatActivity {
    private ListView listView;    
    private void _findViews(){listView = (ListView) findViewById(R.id.listView);    }
    private void _setDBdata(){
        final ArrayAdapter<String> adapter =
                new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1);
        listView.setAdapter(adapter);
        FirebaseDatabase fbDB = FirebaseDatabase.getInstance();        
        DatabaseReference dbRef_chat = fbDB.getReference("chat");        
       dbRef_chat.addValueEventListener(new ValueEventListener() {
            @Override            
             public void onDataChange(DataSnapshot dataSnapshot) {
                adapter.clear();                
                for (DataSnapshot ds : dataSnapshot.getChildren() ){
                    adapter.add(ds.child("name").getValue().toString());                }
            }

            @Override            
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }
    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);        
        setContentView(R.layout.activity_main);        
        _findViews();        
       _setDBdata();    }
}
以上分割了非邏輯行為與資料存取行為
達到函式分工合作,便於修改與擴充


目前 最新的FireBase已進一步將API簡化了
所以只要以下兩行
 FirebaseDatabase fbDB = FirebaseDatabase.getInstance();
 DatabaseReference dbRef_chat = fbDB.getReference("chat");
便能取得資料庫實體物件,更能進一步從"chat"節點進入
接著一個個取出"name"欄位的值
更多API可參考官方文件:
https://firebase.google.com/docs/reference/android/com/google/firebase/database/DatabaseReference

-------------------------------------------------------------------------------------


偵錯

至此,我們能從FireBase取出資料
正確顯示在手機APP上了
那如果出錯呢?

授權沒有設定好? UI沒找到? 資料庫連線錯誤? ....原因

FireBase又給了我們偵錯工具!
我們可以為專案導入偵錯機制
它便會鉅細靡遺地,記錄裝置狀態與回報錯誤資訊:
https://litotom.com/2017/04/19/firebase-crash-reporting/

---------------------------------------------------------

真是太強大了,感恩讚嘆FireBase
讓APP入門容易太多了
且可以迅速發展出"實際地應用"
再也不用煩惱後端架哪裡、網路不給力
而去做一些玩具如:計算機功能、溫度、BMI轉換功能...
或是花一大堆時間,搞一個不安全的會員制度...