0

I am trying to implement a widget in my application. The widget will display a list of scores that are being fetched from Firebase. The problem is that the getViewAt() method is called before the onDataSetChanged() where the list is empty. After the onDataSetChanged() is called, the getViewAt() is never being called again, even if I force refresh with a button.

How can I make this work?

I have tried several solutions found online but it seems that there is something I am missing here.

Here is my class that extends RemoteViewsFactory

public class WidgetDataProvider implements RemoteViewsService.RemoteViewsFactory {

    private List<Scores> scoresList = new ArrayList<>();
    String userId;
    DatabaseReference childNode;
    Context mContext;
    Intent intent;

    WidgetDataProvider(Context mContext, Intent intent) {
        this.mContext = mContext;
        this.intent = intent;
    }

    @Override
    public void onCreate() {
        initializeData();
    }

    @Override
    public void onDataSetChanged() {
        initializeData();
    }

    @Override
    public void onDestroy() {
        scoresList.clear();
    }

    @Override
    public int getCount() {
        return scoresList.size();
    }

    @Override
    public RemoteViews getViewAt(int index) {

        RemoteViews remoteViews = new RemoteViews(mContext.getPackageName(), R.layout.scores_widget_item);
        remoteViews.setTextViewText(R.id.tv_scores_widget_item, scoresList.get(index).getCategoryName());
        remoteViews.setTextViewText(R.id.tv_scores_widget_item_score, scoresList.get(index).getCategoryScore()* 10 + "%");

        return remoteViews;
    }

    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    private void initializeData() throws NullPointerException {
        try {
            scoresList.clear();
            assert FirebaseAuth.getInstance().getCurrentUser() != null;
            userId = FirebaseAuth.getInstance().getCurrentUser().getUid();
            childNode = FirebaseDatabase.getInstance().getReference(DATA_SCORES).child(SCORES_BY_USER).child(userId);
            childNode.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    for (final DataSnapshot category : dataSnapshot.getChildren()) {
                        scoresList.add(new Scores(userId, category.getKey(), Integer.parseInt(category.child(SCORE).getValue().toString())));
                    }
                }
                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            });
        }catch (NullPointerException e){
            Log.d("firebase_exception", "initializeData: " + e.getMessage());
        }
    }
}
Kzaf
  • 563
  • 7
  • 19
  • Please check the duplicate to see why do you have this behaviour. – Alex Mamo Aug 30 '19 at 14:32
  • Hi @AlexMamo, beside the Firebase async issue, I have also another question here. The getViewAt() is never being called again, even if I force refresh with a button. When the getViewAt() is called? Thanks – Kzaf Aug 30 '19 at 14:39
  • Check [this](https://developer.android.com/reference/android/widget/RemoteViewsService.RemoteViewsFactory.html#getViewAt(int)) out. – Alex Mamo Aug 30 '19 at 14:43
  • @Kzaf could you find a solution? If yes, can you please tell me how did you solve your problem? I am stuck with the same issue. – Rishav Naskar Apr 26 '21 at 12:07

0 Answers0