Firebase UI - 编译器会跳过自定义SnapshotParser

问题描述 投票:0回答:2

所以,我正在使用Firebase UI从数据库中获取数据。它看起来像这样:Database

我想迭代“消息”来获取每个孩子,并在我的应用程序中将其显示为消息。这就是我的UserMessage类看起来很相似的方式:

public class UserMessage {

private String mUserLogin;
private String mUserMessage;
private String mUID;

UserMessage(String userLogin, String userMessage, String uid) {
    mUserLogin = userLogin;
    mUserMessage = userMessage;
    mUID = uid;
}

public String getmUserLogin() {
    return mUserLogin;
}

public void setmUserLogin(String mUserLogin) {
    this.mUserLogin = mUserLogin;
}

public String getmUserMessage() {
    return mUserMessage;
}

public String getmUID() {
    return mUID;
}

public void setmUID(String mUID) {
    this.mUID = mUID;
}


public void setmUserMessage(String mUserMessage) {
    this.mUserMessage = mUserMessage;
}

}

我想通过FirebaseRecyclerOptions获取它:

FirebaseRecyclerOptions<UserMessage> options =
            new FirebaseRecyclerOptions.Builder<UserMessage>()
            .setQuery(firebaseDatabaseModel.getQuery(), new SnapshotParser<UserMessage>() {
                @NonNull
                @Override
                public UserMessage parseSnapshot(@NonNull DataSnapshot snapshot) {
                    Log.d("snapshot length", String.valueOf(snapshot.getChildrenCount()));
                    return snapshot.getValue(UserMessage.class);
                }
            })
            .build();

这是我的firebaseDatabaseModel.getQuery()方法的样子:

 public Query getQuery() {
DatabaseReference messageReference =    database.child("messages");
    return messageReference.limitToLast(50);
}

这就是我想在FirebaseRecyclerAdapter中设置数据的方式

class ChatMessagesAdapter extends FirebaseRecyclerAdapter<UserMessage, ChatMessagesAdapter.ChatHolder> {
private UserMessage[] userMessages;

/**
 * Initialize a {@link RecyclerView.Adapter} that listens to a Firebase query. See
 * {@link FirebaseRecyclerOptions} for configuration options.
 *
 * @param options
 */
public ChatMessagesAdapter(@NonNull FirebaseRecyclerOptions<UserMessage> options) {
    super(options);
    userMessages = (UserMessage[]) options.getSnapshots().toArray();
       }

@Override
protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull UserMessage model) {

    holder.message.setText(userMessages[position].getmUserMessage());
    holder.user.setText(userMessages[position].getmUserLogin());

}

@NonNull
@Override
public ChatHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_message, parent, false);
    return new ChatHolder(view);
}

static class ChatHolder extends RecyclerView.ViewHolder {

    @BindView(R.id.user_message)
    TextView message;
    @BindView(R.id.user_login)
    TextView user;

    private ChatHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(itemView);

    }
}

}

问题是,无论我如何通过数组向FirebaseRecyclerAdapter发送选项(用户消息),它总是有0个计数。可能问题在于自定义解析器(我必须正确编写它),但我的调试器只是跳过这部分代码:

 public UserMessage parseSnapshot(@NonNull DataSnapshot snapshot) {
                Log.d("snapshot length", String.valueOf(snapshot.getChildrenCount()));
                return snapshot.getValue(UserMessage.class);
            }

所以我甚至无法检查我在这里做错了什么。我已经尝试了几个小时了,我真的不知道如何处理它。

//编辑1:由于@Alex Malmo建议,我已将数据库密钥更改为:enter image description here

和UserMessage.class:

public class UserMessage {
private String userLogin, userMessage, uid;

public UserMessage() {}

public UserMessage(String userLogin, String userMessage, String uid) {
    this.userLogin = userLogin;
    this.userMessage = userMessage;
    this.uid = uid;
}

public String getUserLogin() { return userLogin; }
public String getUserMessage() { return userMessage; }
public String getUid() { return uid; }

}

看起来事情仍然在FirebaseRecyclerOptions中创建。我试过这两种方法:

FirebaseRecyclerOptions<UserMessage> options = new FirebaseRecyclerOptions.Builder<UserMessage>()
            .setQuery(query,
                    UserMessage.class)
            .build();

    FirebaseRecyclerOptions<UserMessage> options = new FirebaseRecyclerOptions.Builder<UserMessage>()
            .setQuery(query,
                    new SnapshotParser<UserMessage>() {
                        @NonNull
                        @Override
                        public UserMessage parseSnapshot(@NonNull DataSnapshot snapshot) {
                            return snapshot.getValue(UserMessage.class);
                        }
                    })
            .build();

在这两种情况下 - setQuery方法(解析部分)中的第二个参数似乎被忽略(compilator只是跳过那部分 - 它得到正确的查询,并直接转到.build()),这似乎是一个完整的问题,空数据在适配器。

android firebase firebase-realtime-database firebaseui
2个回答
1
投票

您的代码中的问题是您使用错误的getter来填充您的字段。在以小写字母开头的模型类字段中。当您使用名为mUserLogin的字段时,Firebase正在寻找名为getMUserLogin()而不是getmUserLogin()的getter。看大写字母M与小写m字母?这可能是你什么也得不到的最可能的原因。模型类的正确方式应该是这样的:

public class UserMessage {
    private String userLogin, userMessage, uid;

    public UserMessage() {}

    public UserMessage(String userLogin, String userMessage, String uid) {
        this.userLogin = userLogin;
        this.userMessage = userMessage;
        this.uid = uid;
    }

    public String getUserLogin() { return userLogin; }
    public String getUserMessage() { return userMessage; }
    public String getUid() { return uid; }
}

要在数据库中获得正确的数据,只需删除旧数据并添加新数据即可。您的代码现在应该可以使用

你也可以看看Java Naming Conventions


0
投票

好的,我终于解决了。问题是,我完全误解了FirebaseRecyclerOptions函数。我完全确定它在其中传递数据,整个事情是我试图获取数据,而不让整个方法完成它的工作。

所以我改变了适配器结构:

 class ChatMessagesAdapter extends FirebaseRecyclerAdapter<UserMessage, ChatMessagesAdapter.ChatHolder> {
private UserMessage[] userMessages;

/**
 * Initialize a {@link RecyclerView.Adapter} that listens to a Firebase query. See
 * {@link FirebaseRecyclerOptions} for configuration options.
 *
 * @param options
 */
public ChatMessagesAdapter(@NonNull FirebaseRecyclerOptions<UserMessage> options) {
    super(options);
    userMessages = (UserMessage[]) options.getSnapshots().toArray();
       }

@Override
protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull UserMessage model) {

    holder.message.setText(userMessages[position].getmUserMessage());
    holder.user.setText(userMessages[position].getmUserLogin());

}

@NonNull
@Override
public ChatHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_message, parent, false);
    return new ChatHolder(view);
}

static class ChatHolder extends RecyclerView.ViewHolder {

    @BindView(R.id.user_message)
    TextView message;
    @BindView(R.id.user_login)
    TextView user;

    private ChatHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(itemView);

    }
}

至:

class ChatMessagesAdapter extends FirebaseRecyclerAdapter<UserMessage, ChatMessagesAdapter.ChatHolder> {
    private ArrayList<UserMessage> messagesList = new ArrayList<>();

    /**
     * Initialize a {@link RecyclerView.Adapter} that listens to a Firebase query. See
     * {@link FirebaseRecyclerOptions} for configuration options.
     *
     * @param options
     */
    ChatMessagesAdapter(@NonNull FirebaseRecyclerOptions<UserMessage> options) {
        super(options);           }

    @Override
    protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull UserMessage model) {
        messagesList.add(model);
        holder.message.setText(messagesList.get(position).getUserMessage());
        holder.user.setText(messagesList.get(position).getUserLogin());

    }

    @NonNull
    @Override
    public ChatHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_message, parent, false);
        return new ChatHolder(this,view);
    }


    static class ChatHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.user_message)
        TextView message;
        @BindView(R.id.user_login)
        TextView user;

        private ChatHolder(ChatMessagesAdapter chatMessagesAdapter, View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);

        }
    }

}

它完美无缺。我的基础是这个例子:https://www.programcreek.com/java-api-examples/?code=panzerama/Dispatch/Dispatch-master/app/src/main/java/com/indexyear/jd/dispatch/activities/DispatchTeamActivity.java

所以,如果你对整个FirebaseUI有任何问题,我认为上面是正确的例子。

感谢@Alex Malmo和@Yupi的建议!

© www.soinside.com 2019 - 2024. All rights reserved.