Stocarea datelor aplicației dvs. în cloud este foarte importantă în aceste zile, deoarece utilizatorii tind să dețină mai multe dispozitive și doresc ca aplicațiile lor să fie sincronizate între ele. Cu Cloud Firestore, o bază de date NoSQL în timp real disponibilă pe platforma Firebase, acest lucru este mai ușor și mai sigur decât oricând.
Într-un tutorial mai devreme, v-am prezentat toate caracteristicile puternice pe care le oferă Cloud Firestore. Astăzi, vă vom arăta cum să îl utilizați alături de alte produse Firebase, cum ar fi FirebaseUI Auth și Firebase Analytics, pentru a crea o aplicație de urmărire a greutății simplă, dar foarte scalabilă.
Pentru a urma acest tutorial pas cu pas, veți avea nevoie de:
Pentru a putea utiliza produsele Firebase în proiectul Android Studio, veți avea nevoie de pluginul Google Services Gradle, un fișier de configurare Firebase și câteva punerea în aplicare
dependențe. Cu Firebase Assistant, le puteți obține cu ușurință.
Deschide asistentul plecând la Instrumente> Firebase. Apoi, selectați Google Analytics și faceți clic pe Conectați un eveniment Google Analytics legătură.
Acum puteți apăsa butonul Conectați-vă la Firebase pentru a vă conecta proiectul Android Studio la un nou proiect Firebase.
Cu toate acestea, pentru a adăuga efectiv plugin-ul și punerea în aplicare
dependențe, va trebui să apăsați și Adăugați Google Analytics la aplicația dvs. buton.
Aplicația de urmărire a greutății pe care o creăm astăzi va avea doar două caracteristici: stocarea greutăților și afișarea lor ca listă ordonată în ordine inversă cronologică. Desigur, vom folosi Firestore pentru a stoca greutățile. Pentru a le afișa ca o listă, cu toate acestea, vom folosi componente legate de Firestore disponibile în biblioteca FirebaseUI. Prin urmare, adăugați următoarele punerea în aplicare
dependența față de aplicaţia
ale modulului build.gradle fişier:
implementare "com.firebaseui: firebase-ui-firestore: 3.2.2"
Utilizatorii trebuie să aibă posibilitatea să vadă numai greutățile proprii, nu și greutatea fiecăruia care utilizează aplicația. Prin urmare, aplicația noastră trebuie să aibă capacitatea de a-și identifica în mod unic utilizatorii. FirebaseUI Auth oferă această abilitate, deci adăugați următoarea dependență:
implementare "com.firebaseui: firebase-ui-auth: 3.2.2"
De asemenea, vom avea nevoie de câteva widgeturi de design material pentru a oferi aplicației noastre un aspect plăcut. Deci, asigurați-vă că adăugați biblioteca Suport Design și biblioteca Dialoguri materiale ca dependențe.
implementare 'com.android.support:design:26.1.0' implementare 'com.afollestad.material-dialogs: core: 0.9.6.0'
În cele din urmă, apăsați pe Sincronizați acum pentru actualizarea proiectului.
Firebase Authentication acceptă o varietate de furnizori de identitate. Cu toate acestea, toate acestea sunt dezactivate în mod prestabilit. Pentru a activa una sau mai multe dintre ele, trebuie să vizitați consola Firebase.
În consola, selectați proiectul Firebase pe care l-ați creat în pasul anterior, accesați-l Autentificare și apăsați pe Configurați metoda de conectare buton.
Pentru a permite utilizatorilor să se conecteze la aplicația noastră utilizând un cont Google, activați Google ca furnizor, oferiți unui proiect un nume semnificativ cu care se confruntă publicul și apăsați pe Salvați buton.
Google este cel mai simplu furnizor de identitate pe care îl puteți utiliza. Nu are nevoie de nici o configurație și proiectul dvs. Android Studio nu va avea nevoie de alte dependențe pentru acesta.
Trebuie să activați Firestore în consola Firebase înainte de a începe să o utilizați. Pentru a face acest lucru, mergeți la Bază de date și apăsați tasta Incepe butonul prezent în Cloud Firestore Beta card.
Acum vi se va solicita să selectați un mod de siguranță pentru baza de date. Asigurați-vă că alegeți Porniți în modul blocat și apăsați butonul Permite buton.
În modul blocat, în mod implicit, nimeni nu va putea accesa sau modifica conținutul bazei de date. Prin urmare, acum trebuie să creați o regulă de securitate care permite utilizatorilor să citească și să scrie numai acele documente care îi aparțin. Începeți prin deschiderea reguli fila.
Înainte de a crea o regulă de securitate pentru baza noastră de date, trebuie să finalizăm modul în care vom stoca datele în el. Deci, să spunem că vom avea o colecție de nivel superior numită utilizatori
conținând documente care reprezintă utilizatorii noștri. Documentele pot avea ID-uri unice identice cu ID-urile pe care le generează serviciul de autentificare Firebase pentru utilizatori.
Deoarece utilizatorii vor adăuga mai multe intrări în greutate în documentele lor, utilizarea unei sub-colecții pentru a stoca acele intrări este ideală. Să numim sub-colecția greutăți
.
Pe baza schemei de mai sus, putem crea acum o regulă pentru cale utilizatorii / user_id / greutățile / greutate
. Regula va fi aceea că un utilizator este permis să citească și să scrie pe cale numai dacă numele de utilizator
variabila este egală cu ID-ul de autentificare Firebase al utilizatorului.
În consecință, actualizați conținutul editorului de reguli.
serviciu cloud.firestore meci / baze de date / database / documents match / users / user_id / weights / weight permite citirea, scrie: if user_id == request.auth.uid;
În cele din urmă, apăsați pe Publica pentru a activa regula.
Aplicația noastră trebuie să fie utilizabilă numai dacă utilizatorul este conectat la acesta folosind un cont Google. Prin urmare, de îndată ce se deschide, trebuie să verifice dacă utilizatorul are un ID valid de autentificare Firebase. Dacă utilizatorul are ID-ul, acesta ar trebui să meargă înainte și să facă interfața cu utilizatorul. Altfel, ar trebui să afișeze un ecran de conectare.
Pentru a verifica dacă utilizatorul are un ID, putem verifica dacă utilizator curent
proprietate a FirebaseAuth
clasa nu este nulă. Dacă este nulă, putem crea o intenție de conectare prin apelarea createSignInIntentBuilder ()
metodă a AuthUI
clasă.
Următorul cod vă arată cum să faceți acest lucru pentru Google ca furnizor de identitate:
dacă (FirebaseAuth.getInstance (). curentUser == null) // Înscrieți startActivityForResult (AuthUI.getInstance (). createSignInIntentBuilder () .setAvailableProviders (arrayListOf () .build () ), 1) altceva // A fost deja semnat în showUI ()
Rețineți că sunăm o metodă numită showUI ()
dacă există deja un ID valid. Această metodă încă nu există, așa că creați-o și părăsiți acum corpul său gol.
spectacol privat distractiv () // Pentru a face
Pentru a prinde rezultatul intenției de conectare, trebuie să ignorăm onActivityResult ()
metodă a activității. În interiorul metodei, dacă valoarea lui resultCode
argumentul este RESULT_OK
si utilizator curent
proprietatea nu mai este nulă, înseamnă că utilizatorul a reușit să se înregistreze cu succes. În acest caz, trebuie să sunăm din nou showUI ()
pentru a face interfața cu utilizatorul.
Dacă utilizatorul nu reușește să se conecteze, putem afișa un pâine prăjită și închidem aplicația apelând finalizarea()
metodă.
În consecință, adăugați următorul cod la activitate:
(requestCode == 1) if (resultCode == Activity.RESULT_OK && FirebaseAuth.getInstance ()) () .currentUser! = null) // S-a semnat cu succes în showUI () altceva // Conectați-vă la Toast.makeText nereușit (trebuie să vă conectați pentru a continua, Toast.LENGTH_LONG) .show
În acest moment, dacă rulați aplicația pentru prima dată, ar trebui să vedeți un ecran de conectare care arată astfel:
În continuare, datorită programului Google Smart Lock, care este activat implicit, veți fi conectat automat.
Aplicația noastră are nevoie de două planuri: una pentru activitatea principală și una pentru intrările de greutate care vor fi afișate ca elemente ale listei ordonate în ordine cronologică.
Structura activității principale trebuie să aibă a RecyclerView
widget, care va acționa ca listă, și a FloatingActionButton
widget, pe care utilizatorul îl poate apăsa pentru a crea o intrare nouă în greutate. După ce le plasați pe ambele în interiorul unui RelativeLayout
widgetul, fișierul XML de aspect al activității dvs. ar trebui să arate astfel:
Am asociat un handler de evenimente pe clic numit addWeight ()
cu FloatingActionButton
widget. Handlerul nu există încă, așa că creați un stub pentru el în interiorul activității.
fun addWeight (v: Vizualizare) // Pentru a face
Pentru a păstra simplu aspectul introducerii în greutate, vom avea doar două TextView
widget-uri din interiorul acestuia: unul pentru a afișa greutatea și celălalt pentru a afișa ora la care a fost creată înregistrarea. Folosind un LinearLayout
widget ca un container pentru ei va fi suficient.
În consecință, creați un nou fișier XML cu aspect denumit weight_entry.xml și adăugați următorul cod:
În pasul anterior, ați văzut că fiecare intrare în greutate are o greutate și un timp asociat cu aceasta. Pentru a permite companiei Firestore să știe acest lucru, trebuie să creăm un model pentru intrarea în greutate.
Modelele Firestore sunt, de obicei, clase simple de date cu variabilele membre necesare.
clasa de date WeightEntry (greutate var: Double = 0.0, timestamp var: Long = 0)
Acum este, de asemenea, un moment bun pentru a crea un suport de vizualizare pentru fiecare intrare în greutate. Deținătorul de vizualizare, după cum probabil ați ghicit, va fi utilizat de către RecyclerView
widget pentru a reda elementele listate. Deci, creați o nouă clasă numită WeightEntryVH
, care extinde RecyclerView.ViewHolder
clasă și să creeze variabile membre pentru ambele TextView
widget-uri. Nu uitați să le inițializați utilizând findViewById ()
metodă. Următorul cod vă arată cum se face în mod concis:
Clasa WeightEntryVH (itemView: Vizualizare?): RecyclerView.ViewHolder (itemView) var weightView: TextView? = itemView? .findViewById (R.id.weight_view) var timpView: TextView? = itemView? .findViewById (R.id.time_view)
Atunci când un utilizator încearcă să creeze o înregistrare în greutate pentru prima dată, aplicația noastră trebuie să creeze un document separat pentru utilizatorul din interiorul utilizatori
colectare pe Firestore. Așa cum am decis mai devreme, ID-ul documentului nu va fi altceva decât ID-ul de autentificare Firebase al utilizatorului, care poate fi obținut folosind uid
proprietate a utilizator curent
obiect.
Pentru a obține o referință la utilizatori
de colectare, trebuie să folosim Colectie()
metodă a FirebaseFirestore
clasă. Atunci putem să-i sunăm document()
și treceți uid
ca argument pentru a crea documentul utilizatorului.
Va trebui să accesăm documentele specifice utilizatorului atât în timpul citirii, cât și al creării intrărilor de greutate. Pentru a evita codarea logicii de mai sus, vă sugerăm să creați o metodă separată pentru aceasta.
distracție privată getUserDocument (): DocumentReference val db = FirebaseFirestore.getInstance () val users = db.collection ("utilizatori") val uid = FirebaseAuth.getInstance
Rețineți că documentul va fi creat o singură dată pentru fiecare utilizator. Cu alte cuvinte, apelurile multiple la metoda de mai sus vor întoarce întotdeauna același document, atât timp cât utilizatorul utilizează același cont Google.
Când utilizatorii apasă butonul de acțiune plutitor din aplicația noastră, trebuie să poată crea noi intrări în greutate. Pentru a le permite să introducă greutățile lor, să creăm un dialog care să conțină un Editează textul
widget. Cu biblioteca Material Dialog, acest lucru este extrem de intuitiv.
În interiorul addWeight ()
, care servește ca un handler pentru evenimentul on-click al butonului, creați un MaterialDialog.Builder
instanță și numiți-o titlu()
și conţinut()
metode pentru a oferi dialogului dvs. un titlu și un mesaj semnificativ. În mod similar, apelați tip de introducere()
metodă și trecere TYPE_CLASS_NUMBER
ca argument pentru a se asigura că utilizatorul poate introduce numai numere în dialog.
Apoi, apelați intrare()
pentru a specifica un indiciu și a asocia un handler de evenimente cu dialogul. Operatorul va primi greutatea introdusă de utilizator ca argument.
În cele din urmă, asigurați-vă că apelați spectacol()
pentru a afișa dialogul.
MaterialDialog.Builder (acest) .title ("Care este greutatea dvs. de azi?") .InputType (InputType.TYPE_CLASS_NUMBER sau InputType.TYPE_NUMBER_FLAG_DECIMAL) .input ("greutate in kilograme", " _, greutate -> // Să facă) .show ()
În cadrul procesatorului de evenimente, trebuie să adăugăm acum un cod pentru a crea și a completa un nou document de intrare în greutate. Deoarece documentul trebuie să aparțină greutăți
colectarea documentului unic al utilizatorului, pentru a accesa colecția, trebuie să apelați Colectie()
metoda documentului returnat de către getUserDocument ()
metodă.
Odată ce ai colecția, poți să-i suni adăuga()
și să treacă o nouă instanță a WeightEntry
clasați-l pentru a stoca intrarea.
getUserDocument () .collection ("greutăți") .add (WeightEntry (greutate până la șir () până la dublu (), dată ().
În codul de mai sus, puteți vedea că folosim timp
proprietate a Data
pentru a asocia o marcă de timp cu intrarea.
Dacă rulați aplicația acum, ar trebui să puteți adăuga noi intrări în greutate la Firestore. Încă nu le veți vedea în App, dar vor fi vizibile în consola Firebase.
Acum este momentul să populați RecyclerView
widgetul aspectului nostru. Începeți prin a crea o referință pentru aceasta folosind findViewById ()
și atribuirea unei noi instanțe a LinearLayoutManager
clasa la ea. Acest lucru trebuie făcut în interiorul showUI ()
metoda pe care am creat-o mai devreme.
val weightsView = findViewById(Greutatea totală) weightsView.layoutManager = LinearLayoutManager (acest lucru)
RecyclerView
widgetul trebuie să afișeze toate documentele care sunt prezente în interiorul greutăți
colectarea documentului utilizatorului. În plus, ar trebui să apară mai întâi cele mai recente documente. Pentru a îndeplini aceste cerințe, trebuie să creați acum o interogare sunând la Colectie()
și orderby ()
metode.
Din motive de eficiență, puteți limita numărul de valori returnate de interogare apelând limită()
metodă.
Următorul cod creează o interogare care returnează ultimele 90 de intrări în greutate create de utilizator:
val interogare = getUserDocument () colecție ("weights") .orderBy ("timestamp", Query.Direction.DESCENDING) .limit (90)
Utilizând interogarea, trebuie să creați acum o FirestoreRecyclerOptions
obiect, pe care îl vom folosi mai târziu pentru a configura adaptorul nostru RecyclerView
widget. Când treceți întrebare
exemplu la setQuery ()
metoda constructorului său, asigurați-vă că specificați că rezultatele returnate sunt sub formă de WeightEntry
obiecte. Următorul cod vă arată cum să faceți acest lucru:
val opțiuni = FirestoreRecyclerOptions.Builder() .setQuery (interogare, WeightEntry :: class.java) .setLifecycleOwner (this) .build ()
S-ar putea să fi observat că facem activitatea curentă proprietarul ciclului de viață al companiei FirestoreRecyclerOptions
obiect. Acest lucru este important deoarece dorim ca adaptorul nostru să răspundă în mod adecvat la evenimentele comune pe durata ciclului de viață, cum ar fi deschiderea sau închiderea aplicației.
În acest moment putem crea o FirestoreRecyclerAdapter
obiect, care utilizează FirestoreRecyclerOptions
obiect pentru a se configura. Deoarece FirestoreRecyclerAdapter
clasa este abstractă, Android Studio ar trebui să suprascrie automat metodele de generare a codului care arată astfel:
val adapter = obiect: FirestoreRecyclerAdapter(optiune) suprascrie distractie onBindViewHolder (titular: WeightEntryVH, pozitie: Int, model: WeightEntry) // Pentru a face suprascrie fun onCreateViewHolder (parent: ViewGroup ?, viewType: Int): WeightEntryVH // To do
După cum puteți vedea, FirestoreRecyclerAdapter
clasa este foarte asemănătoare cu RecyclerView.Adapter
clasă. De fapt, este derivat din ea. Asta inseamna ca o poti folosi in acelasi mod in care ai putea folosi RecyclerView.Adapter
clasă.
În interiorul onCreateViewHolder ()
metoda, tot ce trebuie să faceți este să umflați weight_entry.xml planificați fișierul și returnați a WeightEntryVH
vizualizați obiectul titularului pe baza acestuia.
val layout = layoutInflater.inflate (R.layout.weight_entry, null) întoarcere WeightEntryVH (layout)
Și înăuntru onBindViewHolder ()
metoda, trebuie să utilizați model
argument pentru a actualiza conținutul TextView
widget-uri care sunt prezente în interiorul suportului de vizualizare.
În timpul actualizării weightView
widget este simplu, actualizarea timeView
widget-ul este ușor complicat, deoarece nu vrem să afișăm semnalul de timp, care este în milisecunde, direct utilizatorului.
Cea mai ușoară modalitate de a transforma marca de timp într-o dată și o dată de citit este să utilizați formatDateTime ()
metodă a DateUtils
clasă. În plus față de marca de timp, metoda poate accepta mai multe drapele diferite, pe care le va folosi pentru a formata data și ora. Sunteți liber să utilizați steaguri care corespund preferințelor dvs..
Afișați data și ora val.dataData = DataUtils.formatDateTime (applicationContext, model.timestamp, DateUtils.FORMAT_SHOW_DATE sau DateUtils.FORMAT_SHOW_TIME sau DateUtils.FORMAT_SHOW_YEAR ) holder.timeView? .text = "Pe $ formattedDate"
În cele din urmă, nu uitați să indicați RecyclerView
widget la adaptorul pe care tocmai l-am creat.
weightsView.adapter = adaptor
Aplicația este gata. Acum ar trebui să puteți adăuga intrări noi și să le puteți vedea imediat în listă. Dacă rulați aplicația pe un alt dispozitiv care are același cont Google, veți vedea că aceleași intrări de greutate apar și pe ea.
În acest tutorial, ați văzut cât de rapid și ușor este să creați o aplicație de urmărire a greutății pe deplin funcțională pentru Android utilizând Cloud Firestore ca bază de date. Simțiți-vă liber să adăugați mai multe funcționalități la acesta! Vă sugerăm, de asemenea, să încercați să o publicați pe Google Play. Cu ajutorul planului Firebase Spark, care oferă acum 1 GB de stocare a datelor gratuit, nu veți avea probleme în a servi cel puțin câteva mii de utilizatori.
Și în timp ce sunteți aici, verificați câteva dintre celelalte postări despre dezvoltarea aplicațiilor Android!