數據庫的使用(Firebase 跟 Redis)總結
一、FireBase Database 的使用 【Android】
最近使用了FireBase 的Database,感覺入坑了,雖然國內需要科學“那個”,不過還是很舒服,拋棄了服務器的開發,直接寫前端,舒服。
這個具體配置還有api key的獲取這裏不多說,我們來看看項目中具體如何使用。
可能會誤人子弟,給別人做demo比較急,有些地方多見諒。
1.實現註冊功能
Java
//firebase database
private FirebaseDatabase mDatabase;
private DatabaseReference myRef;
//init database
mDatabase = FirebaseDatabase.getInstance();
//search from users
myRef = mDatabase.getReference("users");
這個地方是初始化,並獲得users的怎麼說,users是個啥,哈哈差點要說“表”。看一下firebase的後臺吧,這個相當於users key 對應的 value,也就是說mDatabase.getReference(“users”);之後我們拿到了users的調用權。
這個user一看就很簡陋,哈哈,demo,demo。
把註冊信息傳到firebase
myRef.child(et_username.getText().toString())
.setValue(et_password.getText().toString())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Register Success!!!", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Register Fail!!!", Toast.LENGTH_LONG).show();
}
});
這個地方myRef.child(“username”).setValue(“password”),可以看出,我們把key-value的用戶名密碼存儲到users中去了。
後邊這個.addOnSuccessListener(new OnSuccessListener()是監聽事件,插入成功的一個回掉。
完整代碼
package com.example.cacp;
import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class RegisterActivity extends AppCompatActivity {
//Ui
private EditText et_username;
private EditText et_password;
private EditText et_password2;
private Button btn_register;
//firebase database
private FirebaseDatabase mDatabase;
private DatabaseReference myRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
//bind view
et_username = findViewById(R.id.input_username);
et_password = findViewById(R.id.input_password);
et_password2 = findViewById(R.id.input_password_repeat);
btn_register = findViewById(R.id.btn_register);
//init database
mDatabase = FirebaseDatabase.getInstance();
//search from users
myRef = mDatabase.getReference("users");
//button listener
btn_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//progress
final ProgressDialog progressDialog = new ProgressDialog(RegisterActivity.this,
R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Connecting...");
progressDialog.show();
if (et_username.getText().toString().isEmpty() || et_password.getText().toString().isEmpty() || et_password2.getText().toString().isEmpty()) {
Toast.makeText(RegisterActivity.this, "Please enter user information!!!", Toast.LENGTH_LONG).show();
progressDialog.dismiss();
} else {
if (et_password.getText().toString().equals(et_password2.getText().toString())) {
//insert user information
myRef.child(et_username.getText().toString())
.setValue(et_password.getText().toString())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Register Success!!!", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "Register Fail!!!", Toast.LENGTH_LONG).show();
}
});
} else {
progressDialog.dismiss();
Toast.makeText(RegisterActivity.this, "The two passwords do not match!!!", Toast.LENGTH_LONG).show();
}
}
}
});
}
}
2.實現登陸功能
這個就更誤人子弟了,會把整個users中的數據都會拉到本地,哈哈,密碼也被人看到了,demo,demo。
初始化的都一樣,也是拿到users的調用權
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
progressDialog.dismiss();
//auth username password
if(dataSnapshot.child(et_username.getText().toString()).exists()){
String password = dataSnapshot.child(et_username.getText().toString()).getValue().toString();
if(password.equals(et_password.getText().toString())){
Singleton.getInstance().setUsername(et_username.getText().toString());
Toast.makeText(LoginActivity.this,"Login Success!!!",Toast.LENGTH_LONG).show();
startActivity(new Intent(LoginActivity.this,Main2Activity.class));
finish();
}else{
Toast.makeText(LoginActivity.this,"Password Mistake!!!",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(LoginActivity.this,"The username does not exist!!!",Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
progressDialog.dismiss();
}
});
這個 DataSnapshot dataSnapshot 參數中獲取了users的全部數據……
使用 dataSnapshot.child(“username”).exist()判斷一下這個用戶名是不是存在。
如果存在, 再獲取一下這個用戶名對應的密碼dataSnapshot.child(“username”).getValue().toString(),然後跟輸入框裏的比較一下,沒問題就沒問題了。……
完整代碼
package com.example.cacp;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class LoginActivity extends XPermissionActivity {
//ui
private EditText et_username;
private EditText et_password;
private Button btn_login;
private TextView tx_register;
private Context mContext;
private DatabaseReference myRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mContext = this;
//bind view
et_username = findViewById(R.id.input_username);
et_password = findViewById(R.id.input_password);
btn_login = findViewById(R.id.btn_login);
tx_register = findViewById(R.id.tv_register);
// Write a message to the database
FirebaseDatabase database = FirebaseDatabase.getInstance();
myRef = database.getReference("users");
tx_register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
startActivity(new Intent(LoginActivity.this,RegisterActivity.class));
}
});
btn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
requireAll();
}
});
}
//Apply for the necessary permissions first
private void requireAll() {
requestPermission(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION
}, new XPermissionActivity.PermissionHandler() {
@Override
public void onGranted() {
//progress
final ProgressDialog progressDialog = new ProgressDialog(LoginActivity.this,
R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Connecting...");
progressDialog.show();
if(et_username.getText().toString().isEmpty()||et_password.getText().toString().isEmpty()){
Toast.makeText(LoginActivity.this,"Please input username or password",Toast.LENGTH_LONG).show();
progressDialog.dismiss();
}else{
myRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
progressDialog.dismiss();
//auth username password
if(dataSnapshot.child(et_username.getText().toString()).exists()){
String password = dataSnapshot.child(et_username.getText().toString()).getValue().toString();
if(password.equals(et_password.getText().toString())){
Singleton.getInstance().setUsername(et_username.getText().toString());
Toast.makeText(LoginActivity.this,"Login Success!!!",Toast.LENGTH_LONG).show();
startActivity(new Intent(LoginActivity.this,Main2Activity.class));
finish();
}else{
Toast.makeText(LoginActivity.this,"Password Mistake!!!",Toast.LENGTH_LONG).show();
}
}else{
Toast.makeText(LoginActivity.this,"The username does not exist!!!",Toast.LENGTH_LONG).show();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
}
@Override
public boolean onNeverAsk() {
new AlertDialog.Builder(mContext)
.setTitle("Permission to apply for")
.setMessage("Enable permissions in Settings - applications - permissions to ensure the normal use of functions")
.setPositiveButton("Allow", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivity(intent);
dialog.dismiss();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
finish();
}
})
.setCancelable(false)
.show();
return true;
}
});
}
}
3.實現用戶評分功能
我們登陸成功後,需要對上一篇文章搜索到附近的公園進行評分,這個跟註冊差不多。
看一下firebase後臺。
獲取rating的操作權
//firebase database
FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference myRef = database.getReference("rating");
插入評分,只是多了個child
myRef.child(id).child(Singleton.getInstance().getUsername())
.setValue(String.valueOf(v))
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
progressDialog.dismiss();
Toast.makeText(DetailActivity.this, "Rating Success!!!", Toast.LENGTH_LONG).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
progressDialog.dismiss();
Toast.makeText(DetailActivity.this, "Rating Fail!!!", Toast.LENGTH_LONG).show();
}
});
貌似沒有什麼區別,我爲什麼要貼出來……
myRef.child(id).child(“username”).setValue(“3.5”)
公園的id,用戶名,評分,沒毛病。
記錯了,不是這個項目裏的,然後再加一點別的項目裏的,哈哈,不是項目,demo,demo
4.實現文章評論功能
可以看一下firebase的後臺,這裏,comments相當於sql中的表吧,我們下一層是文章id,例如這裏的class of 1927 bear,然後下一層,是一個隨機key,然後下一層就是用戶的評論了,怎麼樣,這個稍微複雜一點吧。
這個怎麼實現呢,看代碼。
初始化一樣
//firebase database
private FirebaseDatabase mDatabase;
private DatabaseReference myRef;
mDatabase = FirebaseDatabase.getInstance();
myRef = mDatabase.getReference("comments").child(title);
這裏我們獲取了comments的操作權,並且向下一層擴展了一下,我們點擊進入這個文章後,獲取了文章的id,就是這個title,也就是我們對這篇文章進行評論,我們的評論都會被插入到這個文章對應的表中。又“表”了,SQL陷的太深。。。。
存儲用戶評論信息
Comment comment = new Comment(editText.getText().toString(), getUsername(), new Date());
myRef.push().setValue(comment);
這裏我們用了Comment,這個是我們自己建的Bean,把一條評論作爲對象進行存儲。
先說一下這個 push(),就是上邊我們看到的文章下一層的隨機key,setValue不用多說了。
然後我們看一下Comment類
Comment.java
package com.example.cs160_sp18.prog3;
import java.util.Date;
// custom class made for storing a message. you can update this class
public class Comment {
public String text;
public String username;
public Date date;
public Comment(){
}
public Comment(String text, String username, Date date) {
this.text = text;
this.username = username;
this.date = date;
}
// returns a string indicating how long ago this post was made
protected String elapsedTimeString() {
long diff = new Date().getTime() - date.getTime();
long seconds = diff / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
long days = hours / 24;
int daysInt = Math.round(days);
int hoursInt = Math.round(hours);
int minutesInt = Math.round(minutes);
if (daysInt == 1) {
return "1 day";
} else if (daysInt > 1) {
return Integer.toString(daysInt) + " days";
} else if (hoursInt == 1) {
return "1 hour";
} else if (hoursInt > 1) {
return Integer.toString(hoursInt) + " hours";
} else {
return "less than an hour";
}
}
}
有用戶名,評論內容,評論時間,下邊還有一個計算多久之前發的這條評論。可以看一下demo界面的展示。
還沒完,我們發送了一條評論之後,可以立即就顯示在上班,使用firebase監聽數據的改變,並把數據添加到recylerview中。
myRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try {
Comment comment = dataSnapshot.getValue(Comment.class);
Log.d("xbw12138",comment.text);
comments.add(comment);
commentAdapter.notifyDataSetChanged();
editText.setText("");
} catch (Exception ex) {
Log.e("MYERROR", ex.getMessage());
}
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d("MYERROR", databaseError.getMessage());
}
});
commentAdapter = new CommentAdapter(this, comments);
recyclerView.setAdapter(commentAdapter);
}
這裏我們也使用了Comment來承接一條評論數據。
感覺一下說的有點多,那個Redis先不在這裏說了,也不是一個內容,誤人子弟了各位,完全是爲了方便實現demo,記錄一下。有需要demo的可以留言評論。