Add extra data to recyclerView - java

I've just recently started to learn some coding, a little python and java.
I'm trying to make a whatsapp clone as a test, and I've hit a wall.
Basically I have a UID showing as the name of a group chat, and I want to swap it for a groupId I have saved in firebase at the same level as the Uid.
FirebaseDatabase.getInstance().getReference().child("chat").child(chatId).child("info").child("groupId)
I've been following simcoder youtube video and there's a lot of checks and balances happening between user and chat UIDs and I'm getting lost in the middle of all that.
I've tried adding groupId to the adapter and the chatObject, and I can see the data in debug, but I just can't get it to populate the recycler view. I've had a search of the forums here, but can't quite get it to work.
I'm hoping someone can help me out, many thanks
private RecyclerView mChatList;
private RecyclerView.Adapter mChatListAdapter;
private RecyclerView.LayoutManager mChatListLayoutManager;
ArrayList<ChatObject> chatList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_group_chat);
OneSignal.startInit(this).init();
OneSignal.setSubscription(true);
OneSignal.idsAvailable(new OneSignal.IdsAvailableHandler() {
#Override
public void idsAvailable(String userId, String registrationId) {
FirebaseDatabase.getInstance().getReference().child("user").child(FirebaseAuth.getInstance().getUid()).child("notificationKey").setValue(userId);
}
});
OneSignal.setInFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification);
Button mLogout = findViewById(R.id.logout);
Button mFindUser = findViewById(R.id.finduser);
mFindUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), FindUserActivity.class));
}
});
mLogout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
OneSignal.setSubscription(false);
FirebaseAuth.getInstance().signOut();
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return;
}
});
getPermissions();
initializeRecyclerView();
getUserChatList();
}
private void getUserChatList(){
DatabaseReference mUserChatDB = FirebaseDatabase.getInstance().getReference().child("user").child(FirebaseAuth.getInstance().getUid()).child("chat");
mUserChatDB.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()){
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()){
ChatObject mChat = new ChatObject(childSnapshot.getKey());
boolean exists = false;
for (ChatObject mChatIterator : chatList){
if(mChatIterator.getChatId().equals(mChat.getChatId()))
exists = true;
}
if (exists)
continue;
chatList.add(mChat);
getChatData(mChat.getChatId());
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void getChatData(String chatId) {
DatabaseReference mChatDB = FirebaseDatabase.getInstance().getReference().child("chat").child(chatId).child("info");
mChatDB.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String chatId = "";
if(dataSnapshot.child("id").getValue() != null)
chatId = dataSnapshot.child("id").getValue().toString();
for(DataSnapshot userSnapshot : dataSnapshot.child("users").getChildren()){
for(ChatObject mChat : chatList)
if(mChat.getChatId().equals(chatId)){
UserObject mUser = new UserObject(userSnapshot.getKey());
mChat.addUserToArrayList(mUser);
getUserData(mUser);
}
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void getUserData(UserObject mUser) {
DatabaseReference mUserDb = FirebaseDatabase.getInstance().getReference().child("user").child(mUser.getUid());
mUserDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserObject mUser = new UserObject(dataSnapshot.getKey());
if(dataSnapshot.child("notificationKey").getValue() != null)
mUser.setNotificationKey(dataSnapshot.child("notificationKey").getValue().toString());
for(ChatObject mChat : chatList)
for(UserObject mUserIt : mChat.getUserObjectArrayList()){
if(mUserIt.getUid().equals(mUser.getUid())){
mUserIt.setNotificationKey(mUser.getNotificationKey());
}
}
mChatListAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
private void initializeRecyclerView() {
chatList = new ArrayList<>();
mChatList = findViewById(R.id.chatList);
mChatList.setNestedScrollingEnabled(false);
mChatList.setHasFixedSize(false);
mChatListLayoutManager = new LinearLayoutManager(getApplicationContext(), RecyclerView.VERTICAL,false);
mChatList.setLayoutManager(mChatListLayoutManager);
mChatListAdapter = new ChatListAdapter(chatList);
mChatList.setAdapter(mChatListAdapter);
}

From what I see you are passing to the adapter an empty list so that's why there's not data to be displayed.
And also, where you are using mChatListAdapter.notifyDataSetChanged();, you don't set before a populated list to the adapter.
I'm not sure which is the data you want to display but you have to collect in a list from the firebase all the information you want to display, for example, if UserObject is what you want, you have to make an ArrayList<UserObject>, to add there all the objects, pass it to the adapter and then call adapter.notifyDataSetChanged() .
You can make function in the adapter, like :
public void setData(ArrayList<YourObject> list){
yourAdapterList = list
this.notifyDataSetChanged()
}
And then call it from your activity/fragment like adapter.setData( /* your populated list */)

Related

Firebase data retrieving issue in android studio

I want to retrieve data from firebase and display it on recycle view. I provided the correct path for data retrieving. But there is some problem i am unable to find it.
This code where i provided the child address.
final DatabaseReference nm= FirebaseDatabase.getInstance().getReference("Cart")
.child("Admin view")
.child(phoneNo)
.child("Products");
nm.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
for (DataSnapshot npsnapshot : dataSnapshot.getChildren())
{
cart l=npsnapshot.getValue(cart.class);
listData.add(l);
}
adapter = new cartAdapterr(listData, AdminShowOrderProductsActivity.this);
rv.setAdapter(adapter);
}
else
{
Toast.makeText(AdminShowOrderProductsActivity.this, "No Data for: " + phoneNo, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
That is the screenshot of my firebase database and emulator. the phone number in toast message which is also present in firebase database. on node Phone number is correct but it shows error.
The way you work is correct, but you have a mistake, which is when the data is modified in Firebase, a new cartAdapterr is created and this operation is wrong.
You must first create an Adapter and then send the data.
for example you can create it onCreate and create a method inside the Adapter that receives List <Cart> as Shown below :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
//..
adapter = new cartAdapterr(this);
loadDataFirebase():
}
void loadDataFirebase(){
final DatabaseReference nm= FirebaseDatabase.getInstance().getReference("Cart")
.child("Admin view")
.child(phoneNo)
.child("Products");
nm.addValueEventListener(new ValueEventListener()
{
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists())
{
for (DataSnapshot npsnapshot : dataSnapshot.getChildren())
{
cart l=npsnapshot.getValue(cart.class);
listData.add(l);
}
adapter.setDataList(listData);
}
else
{
Toast.makeText(AdminShowOrderProductsActivity.this, "No Data for: " + phoneNo, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
In Adapter you have to create this setDataList (List<Cart> cartItems) :
public void setDataList (List<Cart> cartItems ) {
this.cartItems = cartItems;
notifyDataSetChanged();
}

I am having trouble retrieving data from Firebase real time database into String Variables

My code is as below... I am new to this line so any help is appreciated.
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<Contacts> options = new FirebaseRecyclerOptions.Builder<Contacts>().setQuery(ChatsRef, Contacts.class).build();
FirebaseRecyclerAdapter<Contacts, ChatsViewHolder> adapter = new FirebaseRecyclerAdapter<Contacts, ChatsViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final ChatsViewHolder holder, int position, #NonNull Contacts model) {
final String usersIDs = getRef(position).getKey();
final String[] retImage = {"default_image"};
UsersRef.child(usersIDs).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
if (dataSnapshot.hasChild("image")) {
retImage[0] = dataSnapshot.child("image").getValue().toString();
Picasso.get().load(retImage[0]).into(holder.profileImage);
}
final String retName = dataSnapshot.child("name").getValue().toString();
holder.userName.setText(retName);
if (dataSnapshot.child("userState").hasChild("state")) {
String state = dataSnapshot.child("userState").child("state").getValue().toString();
if (state.equals("online")) {
holder.onlineIcon.setVisibility(View.VISIBLE);
}
else if (state.equals("offline")) {
holder.onlineIcon.setVisibility(View.INVISIBLE);
}
}
else {
holder.onlineIcon.setVisibility(View.INVISIBLE);
}
// i am having trouble from this portion onwards
final String[] retLastMessage = {null};
final String[] retLastMessageTime = {null};
final String[] retLastMessageDate = {null};
RootRef.child("Contacts").child(currentUserID).child(usersIDs).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("LastMessage")) {
retLastMessage[0] = dataSnapshot.child("LastMessage").getValue().toString();
retLastMessageTime[0] = dataSnapshot.child("LastMessageTime").getValue().toString();
retLastMessageDate[0] = dataSnapshot.child("LastMessageDate").getValue().toString();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
holder.userLastMessage.setText(retLastMessage[0]);
String retLastMessageTimeDate = retLastMessageTime[0] + " " + retLastMessageDate[0];
holder.userLastMsgTime.setVisibility(View.VISIBLE);
holder.userLastMsgTime.setText(retLastMessageTimeDate);
//upto this I guess
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent chatIntent = new Intent(getContext(), ChatActivity.class);
chatIntent.putExtra("visit_user_id", usersIDs);
chatIntent.putExtra("visit_user_name", retName);
chatIntent.putExtra("visit_image", retImage[0]);
startActivity(chatIntent);
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
#NonNull
#Override
public ChatsViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.users_display_layout, viewGroup, false);
return new ChatsViewHolder(view);
}
};
chatsList.setAdapter(adapter);
adapter.startListening();
}
app is crashing when it tries to retrieve these data from firebase
please help. I am using the above code to actually get the final message and time of last message to display it in chats fragment of my app. the last message and last message time are saved in contacts node
this is how the database entry looks like
So you need to do that :
DatabaseReference reference =
FirebaseDatabase.getInstance().getReference("Contacts").child("2").child("3");
// of course you are not going to use 2 and 3 as a child but it's just to illustrate my point
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
after changing the code a little the app ran smoothly
the changed code is:
final String[] retLastMessage = {null};
final String[] retLastMessageTime = {null};
final String[] retLastMessageDate = {null};
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Contacts").child(currentUserID).child(usersIDs);
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("LastMessage")) {
retLastMessage[0] = dataSnapshot.child("LastMessage").getValue().toString();
retLastMessageTime[0] = dataSnapshot.child("LastMessageTime").getValue().toString();
retLastMessageDate[0] = dataSnapshot.child("LastMessageDate").getValue().toString();
holder.userLastMessage.setVisibility(View.VISIBLE);
holder.userLastMessage.setText(retLastMessage[0]);
String retLastMessageTimeDate = retLastMessageTime[0] + " " + retLastMessageDate[0];
holder.userLastMsgTime.setVisibility(View.VISIBLE);
holder.userLastMsgTime.setText(retLastMessageTimeDate);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
rest of the code remains same. the problem was i was assigning values after the ValueEventListener. i don't know the proper reason but aster assigning the values inside the ValueEventLister the code seems to run fine.

My app only gets the first message i send then stops displaying other nodes

I'm using firebase to store the messages under a randomly generated node , messages are successfully added to this node but, it only displays the first message sent.
Here's my class containing the listeners.
I tried changing the Single event listener in get chat id to a value event listener but it didn't solve the problem.
when I close the chat and open it again it shows the first message only.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
currentUserId = FirebaseAuth.getInstance().getCurrentUser().getUid();
mMatchId = getIntent().getExtras().getString("MatchId");
mDatabaseUser = FirebaseDatabase.getInstance().getReference().child("Users").child(currentUserId).child("connections").child("matches").child(mMatchId).child("ChatId");
mDatabaseChat = FirebaseDatabase.getInstance().getReference().child("Chat");
getChatId();
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
mChatLayoutManager = new LinearLayoutManager(ChatActivity.this);
mRecyclerView.setLayoutManager(mChatLayoutManager);
mChatAdapter = new ChatAdapter(getDataSetChat(), ChatActivity.this);
mRecyclerView.setAdapter(mChatAdapter);
mSendEditText = (EditText) findViewById(R.id.message);
mSendButton = (Button) findViewById(R.id.send);
mSendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendMessage();
}
});
}
private void sendMessage() {
String sendMessageText = mSendEditText.getText().toString();
if(!sendMessageText.isEmpty()){
DatabaseReference newMessageDb = mDatabaseChat.push();
Map newMessage = new HashMap();
newMessage.put("createdByUser", currentUserId);
newMessage.put("text", sendMessageText);
newMessageDb.setValue(newMessage);
}
mSendEditText.setText(null);
}
private void getChatId(){
mDatabaseUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
chatId = dataSnapshot.getValue().toString();
mDatabaseChat = mDatabaseChat.child(chatId);
getChatMessages();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getChatMessages() {
mDatabaseChat.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot t : dataSnapshot.getChildren()) {
String message = null;
String createdByUser = null;
if (t.child("text").getValue() != null) {
message = t.child("text").getValue().toString();
}
if (t.child("createdByUser").getValue() != null) {
createdByUser = t.child("createdByUser").getValue().toString();
}
if (message != null && createdByUser != null) {
Boolean currentUserBoolean = false;
if (createdByUser.equals(currentUserId)) {
currentUserBoolean = true;
}
ChatObject newMessage = new ChatObject(message, currentUserBoolean);
resultChat.add(newMessage);
mChatAdapter.notifyDataSetChanged();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Database image
it is because you first time open the activity and your getChatId() function is called a single time and give you one single id of your single message. and then you pass it on addChildEventListener. so thats y it gives you the single messagr to your recyclerview. if you show ur database schema i will provide youy more specific query
List<Chat> chatMessageList = new ArrayList<>();;
DatabaseReference database = FirebaseDatabase.getInstance()
.getReference()
.child(Common.CHATS);
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
chatMessageList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chat chat = snapshot.getValue(Chat.class);
assert chat != null;
chatMessageList.add(chat);
mChatAdapter = new ChatAdapter(context, chatMessageList);
mRecyclerView.setAdapter(mChatAdapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});

Firebase does not work at the first time?

I want to generate a report pdf counting on total Orders and orders with status wanted
I have this code to create pdf and fill table out
private TemplatePDF templatePDF;
FirebaseDatabase database;
DatabaseReference reference;
Button btnRatio1;
ArrayList<String[]> rowqa=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reportes);
database=FirebaseDatabase.getInstance();
reference=database.getReference("Requests");
btnRatio1=findViewById(R.id.Quality);
btnRatio1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
reference.orderByChild("date").startAt("1530002755582").endAt("1530504865654").
addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
createTemplate(rowqa);
}
});
}
private void showData(DataSnapshot dataSnapshot){
int total=(int)dataSnapshot.getChildrenCount();
int count=0;
String[]row;
for (DataSnapshot myDataSnapshot : dataSnapshot.getChildren())
{
Request rq = myDataSnapshot.getValue(Request.class);
if (rq.getStatuscali().equals("0"))
{
count++;
}
}
row= new String[]{Common.getDate(Long.parseLong("1529945980802")),String.valueOf(count),String.valueOf(total),""+ count/total};
addRow(row);
}
private void createTemplate(ArrayList<String[]> rowqa) {
TemplatePDF templatePDF1 = new TemplatePDF(getApplicationContext());
templatePDF1.openDocument("Quality");
templatePDF1.addTitles("Frutifelles E.I.R.L.","Calidad de pedidos generados","25/06/2018");
templatePDF1.createTable(header,rowqa);
templatePDF1.closeDocument();
templatePDF1.viewPDF();
}
private void addRow(String[]row){
rowqa.add(row);
}
The first time show me my pdf this way
But the second time show me correctly
It seems like first time it doesn't work
just as #Jen Person said, you should put the createTemplate(rowqa) inside the onDataChange callback, else when you click the button at the first time, the rowqa is empty, so createTemplate(rowqa) will get an empty PDF.
an example:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reportes);
btnRatio1=findViewById(R.id.Quality);
btnRatio1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// dateStart, dateEnd should be instance fields
queryData(dateStart, dateEnd);
}
});
}
private void queryData(String dateStart, String dateEnd) {
database=FirebaseDatabase.getInstance();
reference=database.getReference("Requests");
reference.orderByChild("date")
.startAt(dateStart)
.endAt(dateEnd)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
showData(dataSnapshot);
createTemplate(rowqa);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}

How to display data in a recyclerview using FirebaseUI?

I am new to firebase and I am in love with this real-time database thing.
However, I am not sure how to display nested data in a recycled view.
Following is my database structure :-
I want to display the data at 0,1,2...The data consist of information about different books.
This is what I have tried so far:-
private void getSelectedBooks() {
FirebaseRecyclerAdapter<BooksInfo, BooksViewHolder> adapter = new FirebaseRecyclerAdapter<BooksInfo, BooksViewHolder>(
BooksInfo.class,
R.layout.book_list,
BooksViewHolder.class,
nextOrder.child(String.valueOf(index))
) {
#Override
protected void populateViewHolder(BooksViewHolder viewHolder, final BooksInfo model, final int position) {
Log.d("BOOKDETAILS",model.getTitle());
// viewHolder.setTitle(model.getTitle());
// viewHolder.setISBN(model.getISBN());
// viewHolder.setDiscount(model.get());
// viewHolder.setQty(model.getQuantity());
// viewHolder.setPrice(model.getPrice());
// viewHolder.setGrossValue(model.get);
// viewHolder.setNetValue(model.get);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
DatabaseReference ref = getRef(position);
String key = ref.getKey();
Toast.makeText(AddOrderActivity.this, key, Toast.LENGTH_SHORT).show();
// getRetailerInfo(key);
}
});
}
};
selectedBookRecyclerView.setAdapter(adapter);
mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.child(String.valueOf(index)).exists()) {
// run some code
// DisableProgress();
} else {
// DisableProgress();
// Toast.makeText(RetailerActivity.this, "No retailers to display", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Here DatabaseReference nextOrder = mDatabase.child(userId).child("order_details").child(String.valueOf(index));
Any help or suggestion is appreciated.Thank you.

Categories

Resources