> # APP端
[TOC]
# 進入Firebase
請先下載&安裝好Android Studio(文章使用版本為4.0.1)
---
## 登入Firebase&建立專案
### step1:至Firebase 官網登入 gmail

### step2:建立專案
按照步驟輸入如圖



位置看想在哪...應該是都行,然後建立專案!
---
## Android Studio 專案連接firebase設定
### step1:先到Android Studio中完成設定
在Firebase上建立完成新專案之後,如何導入android studio

首先點選android studio程式中右上角進行登入(建立專案的gmail)

點選允許

點選Firebase 接著先回來android studio 點選Tools 選擇 Firebase

接著就可以看需求選擇需要的服務進行連接 (此處使用身分驗證功能作範例)

點選 Email and password authentication

按照上面說明的順序選擇 1.Connect to Firebase

選擇前面已在Firebase上建置的專案

如成功連結 會打勾勾 接著點選
2.Add Firebase Authentication to your app

選擇Accept Changes

將會自動幫你產生到你的gradle
代表你目前的app中已經擁有這項服務(但是還沒有完全連接)
啟用其他服務也是以此類推(只是不用再設定前面的Connect to Firebase)
接下來是最關鍵的步驟
### step2:下載該專案的鑰匙

回到Firebase 網頁 並且重新整理後
發現我們已經成功將兩邊的專案連接在一起了
接著首先點選 專案總覽-->專案設定

可以看到您的應用程式中(已產生我們在Android Studio的專案)
##### 接著點選

請將此檔案放置Android Studio 專案目錄底下的app資料夾中
(如果想要使用別人做好的專案也是如此)


完成之後就可以來開始寫APP的功能囉!
---
# 關於Authentication身分驗證
## 設定e-mail作為驗證方式(使用該服務的入口)
### step1:專案網頁設定

首先先到專案網頁上的 Authentication
點選設定登入方式


點選編輯設定

勾選啟用並儲存
##### 設定e-mail 系統郵件內容

由此設定 可編輯郵件內容
### step2:APP端程式碼
#### 請記得先到Tools 先加入該服務到app中
##### 在app上的登入程式碼
```
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
public class MainActivity extends AppCompatActivity {
EditText emailId , password;
Button btnSignIn;
TextView tvSignUp;
private FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAuth = FirebaseAuth.getInstance();
emailId = findViewById(R.id.EmaileditText);
password = findViewById(R.id.PasseditText);
btnSignIn = findViewById(R.id.BtnSignIn);
tvSignUp = findViewById(R.id.textView3);
btnSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email = emailId.getText().toString();
String pwd = password.getText().toString();
if (email.isEmpty()){
emailId.setError("您尚未輸入信箱");
emailId.requestFocus();
}
else if(pwd.isEmpty()){
password.setError("您尚未輸入密碼");
password.requestFocus();
}
else if (email.isEmpty() && pwd.isEmpty()){
Toast.makeText(MainActivity.this,"請先輸入帳號密碼",Toast.LENGTH_LONG).show();
}
else if(!(email.isEmpty() && pwd.isEmpty())){
mAuth.signInWithEmailAndPassword(email,pwd).addOnSuccessListener(MainActivity.this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
Toast.makeText(MainActivity.this,"您已登入",Toast.LENGTH_SHORT).show();
Intent intToHome = new Intent(MainActivity.this,HomeActivity.class);
startActivity(intToHome);
}
});
}
else {
Toast.makeText(MainActivity.this,"Error",Toast.LENGTH_SHORT).show();
}
}
});
}
}
```
##### 在app上的認證信程式碼
```
public void sendVerificationEmail(){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user !=null){
user.sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful())
{
Toast.makeText(SignUp_page.this,"Sign Up Success pls check your email",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(SignUp_page.this,"Sign Up Error pls try again",Toast.LENGTH_LONG).show();
}
}
});
}
}
```
有關於註冊由於會使用FireStore DB所以這裡先不講。
---
# 關於FireStore 資料庫
## 專案網頁設定
### step1:建立資料庫

至專案網頁上點選建立資料庫

這裡先以測試模式啟動(日後有需要可再修改)
此處也可設定不同使用者之權限

選擇位置(我是都挑亞洲選)
## 在app上透過身分驗證後授權有效使用者
### 請記得先到Tools 先加入該服務到app中
以下將會達成 在app上進行註冊(透過e-mail地址)
註冊時所輸入的資料會儲存在FireStore成功後發送驗證信
如果確認使用者有成功點擊驗證信
才可以進入下一個Activity
### 登入code(包含選擇不同階級引導至不同Activity)
```
package com.example.elderlycare_project;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
public class MainActivity extends AppCompatActivity {
EditText emailId , password;
Button btnSignIn,btnSignUp,btnForget;
private FirebaseAuth mAuth;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("ElderlyCare");
mAuth = FirebaseAuth.getInstance();
emailId = findViewById(R.id.Username);
password = findViewById(R.id.Password);
btnSignIn = findViewById(R.id.login);
btnSignUp = findViewById(R.id.Signup);
btnForget = findViewById(R.id.Forget);
btnForget.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String email = emailId.getText().toString();
mAuth.sendPasswordResetEmail(email).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful())
{
Toast.makeText(MainActivity.this,"Check your mailbox to reset pw ",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(MainActivity.this,"please enter the true mailaddress ",Toast.LENGTH_LONG).show();
}
}
});
}
});
btnSignUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent inToSignUp = new Intent(MainActivity.this,SignUp_page.class);
startActivity(inToSignUp);
}
});
btnSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String email = emailId.getText().toString();
String pwd = password.getText().toString();
if (email.isEmpty() &&pwd.isEmpty())
{
Toast.makeText(MainActivity.this,"please enter AC & pw ",Toast.LENGTH_LONG).show();
}
else if (!(email.isEmpty() &&pwd.isEmpty()))
{
mAuth.signInWithEmailAndPassword(email,pwd).addOnSuccessListener(MainActivity.this,
new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
FirebaseUser user =mAuth.getCurrentUser();
try {
if (user.isEmailVerified()) {
//Toast.makeText(MainActivity.this, "Login Success", Toast.LENGTH_SHORT).show();
String uid = mAuth.getUid();
FirebaseFirestore FFS =FirebaseFirestore.getInstance();
DocumentReference df = FFS.collection("Users").document(uid);
df.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
if (documentSnapshot.getString("Rank").equals("rank1"))
{
String name= documentSnapshot.getString("Name");
String Email= documentSnapshot.getString("Email");
Intent intent = new Intent(MainActivity.this,Rank1HomeActivity.class);
Bundle bundle = new Bundle();
bundle.putString("Email",Email);
intent.putExtras(bundle);
startActivity(intent);
//startActivity(new Intent(getApplicationContext(),Rank1HomeActivity.class));
finish();
}
if (documentSnapshot.getString("Rank").equals("rank2"))
{
startActivity(new Intent(getApplicationContext(), Rank2HomeActivity.class));
//Toast.makeText(MainActivity.this, list.indexOf(1), Toast.LENGTH_SHORT).show();
// bundle.putStringArrayList("Bed",list);
// intent.putExtras(bundle);
// startActivity(intent);
// finish();
//Toast.makeText(MainActivity.this, "Login fail", Toast.LENGTH_SHORT).show();
}
if (documentSnapshot.getString("Rank").equals("rank3"))
{
String Email= documentSnapshot.getString("Email");
Intent intent = new Intent(MainActivity.this,Rank3HomeActivity.class);
Bundle bundle = new Bundle();
bundle.putString("Email",Email);
intent.putExtras(bundle);
startActivity(intent);
finish();
//Toast.makeText(MainActivity.this, "Login fail", Toast.LENGTH_SHORT).show();
}
}
});
}
else{
Toast.makeText(MainActivity.this, "Login fail", Toast.LENGTH_SHORT).show();
}
}
catch (NullPointerException e){}
}
});
}
}
});
}
}
```
### 註冊code(包含選擇不同階級)
```
package com.example.elderlycare_project;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;
import java.util.HashMap;
import java.util.Map;
public class SignUp_page extends AppCompatActivity {
String rankClass; //for firestore rank
Button SignUp;
EditText Username,Usermail,Usertel,password1,password2;
//SaveUserInf users;
private Spinner spinner;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sign_up_page);
spinner = (Spinner)findViewById(R.id.Rankspinner);
setAdapter();
setListener();
final FirebaseAuth mAuth = FirebaseAuth.getInstance();
Username = findViewById(R.id.editTextTextPersonName);
Usermail = findViewById(R.id.editTextTextEmailAddress);
Usertel = findViewById(R.id.editTextPhone);
password1 = findViewById(R.id.editTextTextPassword);
password2 = findViewById(R.id.editTextTextPassword2);
SignUp = findViewById(R.id.SignUp);
SignUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final String mail = Usermail.getText().toString();
final String name = Username.getText().toString();
final String tel = Usertel.getText().toString();
String pwd = password1.getText().toString();
String pwd2 = password2.getText().toString();
final String UserRank = rankClass;
boolean checkfield = mail.isEmpty() || name.isEmpty() || tel.isEmpty() || pwd.isEmpty() || pwd2.isEmpty() || UserRank.equals("null");
if (checkfield)
{
Toast.makeText(SignUp_page.this,"please enter every field",Toast.LENGTH_LONG).show();
}
else {
if (pwd.equals(pwd2)) {
if (UserRank.equals("rank1")) {
//admin sign up
mAuth.createUserWithEmailAndPassword(mail, pwd).addOnSuccessListener(SignUp_page.this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
sendVerificationEmail();
String token = authResult.getUser().getUid();
Toast.makeText(SignUp_page.this, token, Toast.LENGTH_SHORT).show();
FirebaseFirestore FFS = FirebaseFirestore.getInstance();
DocumentReference documentReference = FFS.collection("Users").document(token);
Map<String, Object> userdata = new HashMap<>();
userdata.put("Name", name);
userdata.put("Email", mail);
userdata.put("Rank", UserRank);
userdata.put("Tel", tel);
userdata.put("Token", token);
documentReference.set(userdata).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
});
}
else if (UserRank.equals("rank2")){
//taker sign up
mAuth.createUserWithEmailAndPassword(mail, pwd).addOnSuccessListener(SignUp_page.this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
sendVerificationEmail();
String token = authResult.getUser().getUid();
Toast.makeText(SignUp_page.this, token, Toast.LENGTH_SHORT).show();
FirebaseFirestore FFS = FirebaseFirestore.getInstance();
DocumentReference documentReference = FFS.collection("Users").document(token);
DocumentReference employeedocument = FFS.collection("Employee").document(token);
Map<String, Object> userdata = new HashMap<>();
userdata.put("Name", name);
userdata.put("Email", mail);
userdata.put("Rank", UserRank);
userdata.put("Tel", tel);
userdata.put("Token", token);
//userdata.put("Bed","");
employeedocument.set(userdata).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
documentReference.set(userdata).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
});
}
else if (UserRank.equals("rank3")){
//family sign up
mAuth.createUserWithEmailAndPassword(mail, pwd).addOnSuccessListener(SignUp_page.this, new OnSuccessListener<AuthResult>() {
@Override
public void onSuccess(AuthResult authResult) {
sendVerificationEmail();
String token = authResult.getUser().getUid();
Toast.makeText(SignUp_page.this, token, Toast.LENGTH_SHORT).show();
FirebaseFirestore FFS = FirebaseFirestore.getInstance();
DocumentReference documentReference = FFS.collection("Users").document(token);
DocumentReference familydocument = FFS.collection("Family").document(token);
Map<String, Object> userdata = new HashMap<>();
userdata.put("Name", name);
userdata.put("Email", mail);
userdata.put("Rank", UserRank);
userdata.put("Tel", tel);
userdata.put("Token", token);
familydocument.set(userdata).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
documentReference.set(userdata).addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
});
}
});
}
else {
}
}
}
}
});
}
private void setAdapter(){
String [] rank = getResources().getStringArray(R.array.Rank);
ArrayAdapter <String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,rank);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
}
private void setListener(){
spinner.setOnItemSelectedListener(new Spinner.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
String [] rankdb = getResources().getStringArray(R.array.Rankdb);
rankClass = rankdb[i] ;
}
@Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
public void sendVerificationEmail(){
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user !=null){
user.sendEmailVerification().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful())
{
Toast.makeText(SignUp_page.this,"Sign Up Success pls check your email",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(SignUp_page.this,"Sign Up Error pls try again",Toast.LENGTH_LONG).show();
}
}
});
}
}
}
```
## FireStore RecyclerView
### step1:implementation
```
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'com.firebaseui:firebase-ui-firestore:7.0.0'
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.recyclerview:recyclerview-selection:1.1.0-rc03"
implementation "com.google.android.material:material:1.2.1" //漂浮按鈕
```
### step2:Create item.xml
```
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:background="#FFFFFF">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/text_view_rank3_pose_time"
android:maxLines="1"
android:text="Title"
android:id="@+id/text_view_rank3_pose_pose"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
<TextView
android:id="@id/text_view_rank3_pose_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Bed"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:textAppearance="@style/TextAppearance.AppCompat"/>
<TextView
android:id="@+id/text_view_rank3_pose_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text_view_rank3_pose_pose"
android:layout_alignParentStart="true"
android:text="123" />
</RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
```
### step3:Create list_Model.java
```
package com.example.elderlycare_project.Model;
public class taker_pose_model {
private String Name;
private String Time;
private String Pose;
public taker_pose_model(){}
public taker_pose_model(String Name,String Pose,String Time){
this.Name=Name;
this.Pose=Pose;
this.Time=Time;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public String getTime() {
return Time;
}
public void setTime(String time) {
Time = time;
}
public String getPose() {
return Pose;
}
public void setPose(String pose) {
Pose = pose;
}
}
```
### step4:Create Activity
```
package com.example.elderlycare_project;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import com.example.elderlycare_project.Adapter.rank3_pose_adapter;
import com.example.elderlycare_project.Model.patient_pose_model;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
public class Rank3PoseActivity extends AppCompatActivity {
FirebaseFirestore FFS = FirebaseFirestore.getInstance();
TextView txv,txv2,txv3;
private rank3_pose_adapter adapter;
// private String buuid = (String) txv.getText();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rank3_pose);
setTitle("被照顧者姿勢頁面");
Bundle bundle = getIntent().getExtras();
final String uuid=bundle.getString("uuid");
txv = findViewById(R.id.textView16);//站
txv2 = findViewById(R.id.textView17);//坐
txv3 = findViewById(R.id.textView18);
Button test = findViewById(R.id.testbtn);
// txv = findViewById(R.id.textView30);
//txv.setText(uuid);
setRecyclerView(uuid.trim());
}
private void setRecyclerView(String a){
//Query query = FFS.collection("1d16e844-d471-4911-95eb-554c14e7976ep");
Query query = FFS.collection(a+"p");
FirestoreRecyclerOptions<patient_pose_model> options= new FirestoreRecyclerOptions.Builder<patient_pose_model>()
.setQuery(query,patient_pose_model.class)
.build();
adapter=new rank3_pose_adapter(options);
RecyclerView recyclerView = findViewById(R.id.recycler_view_rank3_pose);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
options.getClass();
//ArrayList<String> c =
}
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
adapter.startListening();
}
}
```
#### Layout
```
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Rank3PoseActivity">
<TextView
android:id="@+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="28dp"
android:text="躺著"
app:layout_constraintBottom_toTopOf="@+id/textView12"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/textView12"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="坐"
app:layout_constraintBottom_toTopOf="@+id/textView11"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/textView11"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="站"
app:layout_constraintBottom_toTopOf="@+id/recycler_view_rank3_pose"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.094"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_rank3_pose"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="150sp"/>
<TextView
android:id="@+id/textView14"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginBottom="28dp"
android:text="各別時間"
app:layout_constraintBottom_toTopOf="@+id/textView12"
app:layout_constraintStart_toStartOf="parent" />
<TextView
android:id="@+id/textView16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="230dp"
android:text="TextView"
app:layout_constraintBottom_toTopOf="@+id/recycler_view_rank3_pose"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView11"
app:layout_constraintTop_toBottomOf="@+id/textView17"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/textView17"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="230dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView12"
app:layout_constraintTop_toBottomOf="@+id/textView18" />
<TextView
android:id="@+id/textView18"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="90dp"
android:layout_marginEnd="230dp"
android:text="TextView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.489"
app:layout_constraintStart_toEndOf="@+id/textView13"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/testbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginTop="85dp"
android:layout_marginBottom="17dp"
android:text="Button"
app:layout_constraintBottom_toTopOf="@+id/recycler_view_rank3_pose"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView12"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
```
### step5:Create adapter
```
package com.example.elderlycare_project.Adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.elderlycare_project.Datechange.SecondtoDate;
import com.example.elderlycare_project.Model.patient_pose_model;
import com.example.elderlycare_project.R;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
public class rank3_pose_adapter extends FirestoreRecyclerAdapter<patient_pose_model,rank3_pose_adapter.rank3_pose_Holder>{
public rank3_pose_adapter(@NonNull FirestoreRecyclerOptions<patient_pose_model> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull rank3_pose_adapter.rank3_pose_Holder holder, int position, @NonNull patient_pose_model model) {
holder.txttime.setText(SecondtoDate.getSecDate(model.getTime()));
holder.txtname.setText(model.getName());
holder.txtpose.setText(model.getPose());
}
@NonNull
@Override
public rank3_pose_Holder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rank3_pose_item,parent,false);
return new rank3_pose_Holder(v);
}
class rank3_pose_Holder extends RecyclerView.ViewHolder{
TextView txtname;
TextView txtpose;
TextView txttime;
public rank3_pose_Holder(View rank3_pose_item){
super(rank3_pose_item);
txtname=rank3_pose_item.findViewById(R.id.text_view_rank3_pose_name);
txtpose=rank3_pose_item.findViewById(R.id.text_view_rank3_pose_pose);
txttime=rank3_pose_item.findViewById(R.id.text_view_rank3_pose_time);
}
}
}
```
### 參考影片
https://www.youtube.com/watch?v=ub6mNHWGVHw
---
# 關於Cloud Messaging
https://medium.com/firebase-developers/mobile-app-push-notification-with-firebase-cloud-functions-and-realtime-database-194a82e43ba
尚未實作成功
---
# 關於Cloud Functions
### step1: 安裝Firebase CLI Reference
首先我們先至官網
https://firebase.google.com/docs/cli

可以看到有兩種選項(這裡使用npm)
因此我們必須先裝 "Node.js" 才能繼續操作
至Node.js官網下載
https://nodejs.org/en/

裝LTS版本就行
安裝完後請打開終端機(命令提示字元)
(右鍵win選擇)
[Windows PowerShell系統管理員]。
☆macOS使用也是相同☆ 開啟 終端機

按照網頁說明輸入
npm install -g firebase-tools


安裝完之後就可以來進行登入帳號囉!
輸入 "firebase login" 選擇Y

### step2: 登入Firebase CLI Reference
接著便會引導到Browser 的登入畫面

選擇允許

成功登入CLI


### step3: 初始化Firebase CLI Reference
首先請你先找一個地方建一個新資料夾(英文名稱)
接著使用 cd 指令 到該資料夾中
輸入指令 firebase init

輸入Y

這裡就是看你需要哪些服務
需要的用空白鍵去標記
我只使用Functions 故僅標記 Functions

確認請按Enter

接著根據你的需求選擇相對應的選項
這裡我是選使用已存在的專案

語言選擇JS

選項都默認選Y就可以了

完成後可以發現資料夾內已有產生檔案
### step4:開始使用
由於node.js我不太熟
為了讓他能夠成功發布
因此我們必須先去修改使用的版本

首先先至剛剛CLI的目錄底下的functions資料夾中
開啟package.json 並修改

然後我們就可以開始寫想要的cloud function了
修改方式,編輯index.js
接著透過 終端機 到該目錄底下
輸入指令 firebase deploy
如通過規則,便能成功發布。
#### 原始的index.js

#### 修改過的index.js

#### 成功發布後 可在Functions中顯示

#### 參考影片
https://www.youtube.com/watch?v=Y6jMKQ9zo-o
---
# 時間轉換 java
## 日期轉換成秒數
import java.util.Calendar;
public class DatetoSecond {
private String year ;
private String month;
private String day;
public DatetoSecond(int year ,int month,int day )
{
this.year=String.valueOf(year);
this.month=String.valueOf(month);
this.day=String.valueOf(day);
daytosec(year,month,day);
}
public static String daytosec(int year, int month, int day)
{
Calendar calendar = Calendar.getInstance();
calendar.set(year,month,day,0,0,0); //年月日
long daytosec = calendar.getTimeInMillis();
return String.valueOf(daytosec);
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getMonth() {
return month;
}
public void setMonth(String month) {
this.month = month;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
}
## 秒數轉換成日期
import android.util.Log;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class SecondtoDate {
private String seconds;
public SecondtoDate(String seconds)
{
this.seconds = seconds;
int i = Integer.parseInt(seconds);//+28800;
String ii = String.valueOf(i);
getSecDate(ii);
} public static String getSecDate(String seconds)
{
if(seconds==null) return "";
else {
Date date = new Date();
try{
date.setTime(Long.parseLong(seconds)*1000);
}
catch (NumberFormatException ignored){}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ", Locale.TAIWAN);
return sdf.format(date);
}
}
public String getSeconds() {
return seconds;
}
public void setSeconds(String seconds) {
this.seconds = seconds;
}
}
---
# 計算不同動作時間
## Pseudocode
private void timeCount(ArrayList pos_arr,
ArrayList moment_arr){
int sumA = sumB = sumC = 0;
int currentTime = time.getCurrent();
int i = 0;
for (int i=0; i<pos_arr.length-1;i++){
if(pos == "sit"){
sumA += mommenmt_arr.get(i+1)-
}
else if (pos == 'stand'){}
}
if(pos_arr.get(pos.arr.length)-1 == 'sit'){
sumA += currentTime - momment_arr.get(moment_arr.get
(momment_arr.length-1)));
}
}
---