Ski*_*ᴉʞS 5 android firebase firebase-realtime-database
我有一个Firebase Database
看起来像:
我有一个名为的节点 Products
Products
|
|--------prod1_id
| |
| |--name : "prod1"
| --state: "free"
|
|
|---------prod2_id
|
|--name : "prod2"
--price: "not_free"
Run Code Online (Sandbox Code Playgroud)
然后我有用户的节点
Users
|
|--------user1_id
| |
| |--name : "user1"
| --e-mail: "user1@email.com"
|
|
|---------user2_id
|
|--name : "user2"
--e-mail: "user2@email.com"
Run Code Online (Sandbox Code Playgroud)
在我的应用程序上,用户可以购买,只有当他/她这样做时,我才会创建一个新的节点PurchasedItems
,在那里我存储了User
和Product
Purchased items
|
|--------user1_id
| |
| |--prod1: "any_value"
| --prod2: "any_value"
|
|
|---------user2_id
|
|--prod1: "any_value"
Run Code Online (Sandbox Code Playgroud)
问题在于我对对象的查询,我这样做:
products_ref= FirebaseDatabase.getInstance().getReference().child("products");
Run Code Online (Sandbox Code Playgroud)
登录到应用程序的用户,即使他已经购买了产品,也会显示productNotFree布局,因为在产品上我没有提及用户购买此商品的内容,但我的"TryToPurchase"方法有类似之处,我有一个查询,PurchasedProducts
以查看用户是否有此产品或不进行购买.
在我的onClick()
方法中,我有这个来检查用户是否已经付款
root_ref.child("PurchasedProducts").child(currentuser).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.hasChild(model.getProduct_id())){
showToast("He has that product");
}
else{
showToast("Purchasing");
//Purchase for it
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Run Code Online (Sandbox Code Playgroud)
到目前为止,我有这个switch()
声明,setImageResource
但从查询到products
注意:layoutFree例如是一个没有锁定的盒子,而layoutNotFree是同一个盒子但带锁
switch (model.getState()) {
case "free":
holder.card_image.setImageResource(layoutFree);
break;
case "not_free":
holder.card_image.setImageResource(layoutNotFree));
break;
default:
break;
}
Run Code Online (Sandbox Code Playgroud)
现在我已经面临如果用户购买物品,即使他购买了物品,他/她也无法看到layoutFree,即使他/她已付款,他也会看到带锁的布局.
在onBindViewHolder
我有switch()
声明的地方,我可以再Firebase
询问是否currentUser
有这个产品,如果他有这个产品,我把freeLayout放在NotFreeLayout上.
但我觉得它有点脏,所以我把它放在这里,看看是否还有另一种方法可以提高效率.
好吧,如果我是以支付一种产品的用户身份登录的,该产品的状态为"not_free",我希望看到产品的布局没有锁定项目,如果我支付一个项目,我创建一个表purchasedItems
,我做这样的事情:
root_ref.child("PurchasedProducts").child(currentuser).child(productId).setValue("paid");
Run Code Online (Sandbox Code Playgroud)
而且我也希望看到RecyclerView
layoutNotFree到layoutFree 的更改,是否可以通过任何方式进行更新而不是刷新Activity
?刷新Activity
意味着我必须重新做适配器,创建RecyclerView
等...
我希望我已经正确地解释它并且一步一步地避免混淆,如果我在问题上做错了,可以随意编辑它或者向我提问并且我会编辑.
在此示例中,所有产品表子项均保存在一个 ArrayList
表中,仅对.Firebase Database
根据您的数据库架构。
首先,定义一个Arraylist
ofProducts.class
来保存所有产品详细信息
ArrayList<Products> productsArrayList = new ArrayList<>();
Run Code Online (Sandbox Code Playgroud)
二、定义Products.class
新类中的
public class Products {
public String id;
public String name;
public String state;
public Products() {
}
public Products(String name, String state) {
this.name = name;
this.state = state;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getState() {
return state;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setState(String state) {
this.state = state;
}
}
Run Code Online (Sandbox Code Playgroud)
我只添加id
(位置搜索必需的),,name
您state
可以添加其他值Products.class
第三,进行 Firebase 查询以获取所有产品子项
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Products");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// for loop will be executed for each children
for(DataSnapshot userSnapshot : dataSnapshot.getChildren()){
// put snapShot in Products.class ...... only children added
// in This case Children Will be price, quantity
Products products = userSnapshot.getValue(Products.class);
// set id manually to tha same instance of the class
products.setId(userSnapshot.getKey());
// add the Post class to ArrayList
productsArrayList.add(products);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
//handle databaseError
}
});
Run Code Online (Sandbox Code Playgroud)
现在,在保存产品详细信息后,productsArrayList
您可以在任何地方使用它们。
用于搜索ArrayList<Products>
和获取特定内容的辅助方法position
public int getArrayListProductsPosition(String id){
for(int i = 0; i < productsArrayList.size() ; i++){
// if the passed id equals some id in arrayList return arrayList position
if(Objects.equals(productsArrayList.get(i).getId(), id)){
return i;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第四,现在班级中的任何地方,如果您需要访问特定产品详细信息(UI
例如更新);
// pass the id of the product you want to get details about
// I suppose this id will probably be retrived from another database tabel
int position = getArrayListProductsPosition(id);
//update your UI TextView quantity for example;
String name = productsArrayList.get(position).getName()
textQuantitiy.setText(name);
// or update you UI ImageView for example;
Run Code Online (Sandbox Code Playgroud)
为了提高效率
-在搜索方法( getArrayListProductsPosition
)中,将id's
数据库中的产品保存为数字并更改为Products.class
.
String id
因为Long id
比较比比String-String
较慢Long-Long
--如果要更改产品表(不是静态的),请使用productsArrayList
一次并在检索后立即进行查询(您不希望数据变旧)
归档时间: |
|
查看次数: |
244 次 |
最近记录: |