【问题标题】:Empty ArrayList - Firebase Data RetrievalEmpty ArrayList - Firebase 数据检索
【发布时间】:2017-03-27 14:19:47
【问题描述】:

我目前正在尝试在我的 firebase 数据库上运行查询,我可以在日志中看到我想要的值,但我的方法总是返回一个空数组列表。

请在下面找到我的代码:

public static ArrayList<Transaction> getUserTransactions(String userId){
    Query userTransactionQuery = mDatabaseReference
            .child("transactions")
            .orderByChild("userId")
            .equalTo(userId);

    final ArrayList<Transaction> transactionsByUser = new ArrayList<>();

    userTransactionQuery.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot transactionSnapshot: dataSnapshot.getChildren()) {
                // TODO: handle the post
                Transaction t = transactionSnapshot.getValue(Transaction.class);
                transactionsByUser.add(t);
                Log.w(TAG, t.toString());
            }

            Log.i(TAG, "Collected User Transactions");
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            // Getting Transaction failed, log a message
            Log.w(TAG, "loadTransactions:onCancelled", databaseError.toException());
            // ...
        }
    });

    return transactionsByUser;
}

我的 POJO:

public class Transaction {
    private String id;

    private String userId;

    private String categoryId;

    private TransactionType transactionType;

    private String creationDate;

    private long amount;

    private String description;
    /**
     * No args constructor
     */
    public Transaction () {}


    /**
     * Constructor for the Transaction object
     * @param userId id of the user who made the transaction
     * @param categoryId ID of the category the transaction belongs under
     * @param amount amount spent/received
     * @param transactionType income/expense
     */
    public Transaction(String userId, String categoryId, TransactionType transactionType, long amount, String description) {
        this.userId = userId;
        this.categoryId = categoryId;
        this.transactionType = transactionType;
        this.amount = amount;

        this.description = description;

        //Date last changed will always be set to ServerValue.TIMESTAMP
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String currentDateTime = dateFormat.format(new Date()); // Find todays date

        this.creationDate = currentDateTime;
    }

    /**
     * Transaction Id Getter
     * @return transaction Id
     */
    public String getId() {
        return id;
    }

    /**
     * Transaction Id Setter
     * @param id Id to assign to the user
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * Category Id getter
     * @return category Id under which the transaction belongs
     */
    public String getCategoryId() {
        return categoryId;
    }

    /**
     * Category Id setter
     * @param categoryId  category Id under which the transaction belongs
     */
    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    /**
     * Transaction type getter
     * @return type of the transaction whether its an income or an expense
     */
    public TransactionType getTransactionType() {
        return transactionType;
    }

    /**
     * Transaction type setter
     * @param transactionType type of the transaction to set
     */
    public void setTransactionType(TransactionType transactionType) {
        this.transactionType = transactionType;
    }

    /**
     * Transaction creation date getter
     * @return creation date of the transaction
     */
    public String getCreationDate() {
        return creationDate;
    }

    /**
     * Transaction creation date setter
     * @param creationDate creation date to set to the transaction
     */
    public void setCreationDate(String creationDate) {
        this.creationDate = creationDate;
    }

    /**
     * Transaction amount getter
     * @return amount set
     */
    public long getAmount() {
        return amount;
    }

    /**
     * Transaction amount setter
     * @param amount amount to set
     */
    public void setAmount(long amount) {
        this.amount = amount;
    }

    /**
     * User Id getter
     * @return user id corresponding to the transaction
     */
    public String getUserId() {
        return userId;
    }

    /**
     * User Id setter
     * @param userId user id to set to the transaction
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }

    /**
     * Description getter
     * @return Description corresponding to the transaction
     */
    public String getDescription() {
        return description;
    }
    /**
     * Description setter
     * @param description Description to set to the transaction
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Transaction object string representation
     * @return object represented in a string
     */
    @Override
    public String toString() {
        return "Transaction{" +
                "id='" + id + '\'' +
                ", userId='" + userId + '\'' +
                ", categoryId='" + categoryId + '\'' +
                ", transactionType=" + transactionType +
                ", creationDate='" + creationDate + '\'' +
                ", amount=" + amount +
                '}';
    }
}

我的 JSON 树如下所示:

{
  transactions:
    {
      transactionId {
        pojo
      }
  }        
}

简而言之:我要做的是获取用户使用他的用户 ID 进行的所有交易,我试图将结果存储在数组列表中,但数组列表总是返回空;

【问题讨论】:

  • 所以这个日志:Log.w(TAG, t.toString());返回一个值?
  • @ChesterCobus 不,它会打印我的 POJO 的字符串表示形式。
  • 我的意思是当它运行时会记录 POJO 的值吗?
  • @ChesterCobus 哦,对不起,我误会了,是的。
  • 我认为发生的事情是事件在返回列表后触发,这就是它为空的原因。

标签: android firebase firebase-realtime-database pojo


【解决方案1】:

所以这只是试图回答你的问题:

public static void getUserTransactions(String userId, final ArrayList<Transaction> transactionsByUser){
Query userTransactionQuery = mDatabaseReference
        .child("transactions")
        .orderByChild("userId")
        .equalTo(userId);

userTransactionQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot transactionSnapshot: dataSnapshot.getChildren()) {
            // TODO: handle the post
            Transaction t = transactionSnapshot.getValue(Transaction.class);
            transactionsByUser.add(t);
            Log.w(TAG, t.toString());
        }

        Log.i(TAG, "Collected User Transactions");
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Getting Transaction failed, log a message
        Log.w(TAG, "loadTransactions:onCancelled", databaseError.toException());
        // ...
    }
});
}

用法

ArrayList<Transaction> transactions = new ArrayList<>();

getUserTransactions("{userId}", transactions);

//check after method call while debugging if transactions is empty

如果这不起作用,您将不得不在使用 ArrayList 的地方使用此事件实现。请注意,Firebase 查询是异步的。

【讨论】:

    【解决方案2】:

    使用LiveData解决asynchronous操作中的同步问题。

    private static MutableLiveData<ArrayList<Transaction>> mutableTransactionsByUser = new MutableLiveData<>();
    
    public static MutableLiveData<ArrayList<Transaction>> getUserTransactions(String userId){
        Query userTransactionQuery = mDatabaseReference
                .child("transactions")
                .orderByChild("userId")
                .equalTo(userId);
    
        final ArrayList<Transaction> transactionsByUser = new ArrayList<>();
    
        userTransactionQuery.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot transactionSnapshot: dataSnapshot.getChildren()) {
                    // TODO: handle the post
                    Transaction t = transactionSnapshot.getValue(Transaction.class);
                    transactionsByUser.add(t);
                    Log.w(TAG, t.toString());
                }
    
                //Post here
                mutableTransactionsByUser.postValue(transactionsByUser);
                Log.i(TAG, "Collected User Transactions");
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
                // Getting Transaction failed, log a message
                Log.w(TAG, "loadTransactions:onCancelled", databaseError.toException());
                // ...
            }
        });
    
        return mutableTransactionsByUser;
    }
    

    然后从您的Activity/Fragment 观察如下:

    getUserTransactions(userId).observe(this, new Observer<ArrayList<Transaction>>() {
        @Override
        public void onChanged(ArrayList<Transaction> transactions) {
            // Do your operation here
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-16
      • 1970-01-01
      • 2017-01-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多