Firebase查询可优化

时间:2017-12-31 17:36:11

标签: android firebase firebase-realtime-database

我有Firebase Database看起来像:

我有一个名为Products

的节点
 Products
    |
    |--------prod1_id
    |         | 
    |         |--name : "prod1"
    |          --state: "free"
    |         
    |
    |---------prod2_id
              | 
              |--name : "prod2"
               --price: "not_free"

然后我有用户的节点

Users
     |
     |--------user1_id
     |         | 
     |         |--name : "user1"
     |          --e-mail: "user1@email.com"
     |          
     |
     |---------user2_id
               | 
               |--name : "user2"
                --e-mail: "user2@email.com"

在我的应用程序上,用户可以购买,只有当他/她这样做时,我才会创建一个名为PurchasedItems的新节点,我在其中存储UserProduct

Purchased items
             |
             |--------user1_id
             |         | 
             |         |--prod1: "any_value"
             |          --prod2:  "any_value"
             |         
             |
             |---------user2_id
                       | 
                       |--prod1: "any_value"

问题在于我对对象的查询,我这样做:

 products_ref= FirebaseDatabase.getInstance().getReference().child("products");

什么是问题?

登录到应用程序的用户,即使他已经购买了产品,也会显示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) {

    }
});

到目前为止,我向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;
    }

现在我已经面临过,如果用户购买了一件物品,即使他购买了物品,他/她也无法看到layoutFree,即使他/她已付款,他也会看到带锁的布局

我曾想过要做什么?

在同一onBindViewHolder我有switch()语句的情况下,我可以向Firebase询问currentUser是否有此产品,如果他有该产品我放了freeLayout否则为NotFreeLayout。

但是我觉得它有点脏,所以我把它放在这里,看看是否还有另一种方法可以提高效率。

我想看到什么?

好吧,如果我是以支付了一种状态为“not_free”的产品的用户身份登录的话,我希望看到产品的布局没有锁定项目,如果我付了一个项目,我就创建了一个表purchasedItems,我这样做:

root_ref.child("PurchasedProducts").child(currentuser).child(productId).setValue("paid");

而且我还希望RecyclerView将layoutNotFree更改为layoutFree,是否可以通过任何方式执行此操作而不是刷新Activity?刷新Activity意味着我必须重新执行适配器,创建RecyclerView等...

我希望我已经正确地解释它并且一步一步地避免混淆,如果我在问题上做错了,可以随意编辑或向我提问并且我会编辑。

2 个答案:

答案 0 :(得分:3)

在此示例中,所有产品表格儿童保存在一个 ArrayList仅一个请求到{{1} }。

根据您的数据库架构。

首先,定义Firebase Database Arraylist以保留所有产品详情

Products.class

其次,在新课程中定义 ArrayList<Products> productsArrayList = new ArrayList<>();

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; } } (位置搜索所需),idname 您可以将其他值添加到state

第三,使Firebase查询让所有产品成为子女

Products.class

现在,在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 } }); 中保存产品详细信息后,您可以在任何地方使用它们。

帮助方法,可在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; } ;

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; ),将数据库中的产品getArrayListProductsPosition保存为数字并更改为id'sProducts.classString id 因为Long id比较慢于String-String比较

- 如果要更改Products表(非静态),请在检索查询后立即使用Long-Long一次(您不希望数据变旧)

答案 1 :(得分:0)

要确保代码已优化,您可以使用共享首选项为用户保存购买的ID。访问数据库可能会导致程序流延迟。使用数据快照检索产品ID并将其存储在共享首选项变量并在访问产品详细信息时检查产品ID以显示免费布局。您还可以将项目购买信息保存在用户ID子项中以获取更多指定内容搜索