Sender & Receiver view is not created in my chat Application - java

My sender messages & receiver messages are sent only in the sending messages and there is no in the received view.
I added the following code
database.getReference().child("chats")
.child(senderRoom)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
messageModels.clear();
for (DataSnapshot snapshot1 : snapshot.getChildren())
{
MessageModel model = snapshot1.getValue(MessageModel.class);
model.setMessageId(snapshot1.getKey());
messageModels.add(model);
}
chatAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
but every time I send a new message the app gives the error of "the app is not responding"
and after that, as I said all sent messages appeared in sender view, not receivers.
This is the error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: myapp.files.memochatting, PID: 23966
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at myapp.files.memochatting.Adapter.ChatAdapter.onBindViewHolder(ChatAdapter.java:81)
The line (81) he refers to is:
viewHolder.senderMsg.setText(messageModel.getMessage());
My database looks like this:
{
"Users" : {
"9tDjCkxCnISIzOS1TvHmGwgFSG93" : {
"email" : "maha#gmail.com",
"password" : "123456789",
"userName" : "maha"
},
"PJFr3Lw0EcWLN275GdOqSDHR76D2" : {
"email" : "asmaa.11#gmail.com",
"password" : "123456789",
"userName" : "Asmaa"
},
"T9oPNFhHVadWySFt0ILA6D6XRRm1" : {
"email" : "ahmed#gmail.com",
"password" : "123456789",
"userName" : "ahmed"
},
"WtO1EJijSfgeF9JsVsMG7ZOSbjP2" : {
"profilePic" : "https://lh3.googleusercontent.com/a-/AOh14GggNZN75jHuTl1ZB5ZuQm26aXbT4DvLFGX1_OE0Kw=s96-c",
"userId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2",
"userName" : "Maha Abd El-Moneam"
},
"moTrPYohePOFiX7kSLzOVYdbq1F2" : {
"email" : "mohamed#gmail.com",
"password" : "123456789",
"userName" : "mohamed"
}
},
"chats" : {
"9tDjCkxCnISIzOS1TvHmGwgFSG93PJFr3Lw0EcWLN275GdOqSDHR76D2" : {
"-MsdYoWZISiMbPaCDgLC" : {
"message" : "hello maha, I'm asmaa",
"timestamp" : 1641374739108,
"uId" : "9tDjCkxCnISIzOS1TvHmGwgFSG93"
},
"-Msd_2cuQOPDrU8G7_vS" : {
"message" : "hi asmaa",
"timestamp" : 1641375063018,
"uId" : "9tDjCkxCnISIzOS1TvHmGwgFSG93"
}
},
"9tDjCkxCnISIzOS1TvHmGwgFSG93WtO1EJijSfgeF9JsVsMG7ZOSbjP2" : {
"-MsdIrPbq7PFLRFSD-Pa" : {
"message" : "hellow from me",
"timestamp" : 1641370555853,
"uId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2"
},
"-MsdIvG06F3EgjtdTzEY" : {
"message" : "please receive",
"timestamp" : 1641370570841,
"uId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2"
},
"-MsdWGk0UBnm0Nch14uG" : {
"message" : "hello",
"timestamp" : 1641374072522,
"uId" : "9tDjCkxCnISIzOS1TvHmGwgFSG93"
},
"-MsdWukKtbmNNE8-lrPu" : {
"message" : "hi maha.gmail",
"timestamp" : 1641374240472,
"uId" : "9tDjCkxCnISIzOS1TvHmGwgFSG93"
}
},
"T9oPNFhHVadWySFt0ILA6D6XRRm1null" : {
"-MsKNncf-SlE2I-hwsj6" : {
"message" : "hello ahmed",
"timestamp" : 1641036308698
}
},
"WtO1EJijSfgeF9JsVsMG7ZOSbjP29tDjCkxCnISIzOS1TvHmGwgFSG93" : {
"-MsdIrEwWMoEep3buSCK" : {
"message" : "hellow from me",
"timestamp" : 1641370555853,
"uId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2"
},
"-MsdIuv8E0e74zv_WyY4" : {
"message" : "please receive",
"timestamp" : 1641370570841,
"uId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2"
},
"-MsdXVMa8zEt_sB0unfP" : {
"message" : "from maha to mahagmail",
"timestamp" : 1641374394307,
"uId" : "WtO1EJijSfgeF9JsVsMG7ZOSbjP2"
}
},
"WtO1EJijSfgeF9JsVsMG7ZOSbjP2null" : {
"-MsKNk5TBVnuhZikCdSs" : {
"message" : "hi maha",
"timestamp" : 1641036294080
},
"-MsdBScowXAo-Tti8zcM" : {
"message" : "please",
"timestamp" : 1641368615680
}
},
"nullT9oPNFhHVadWySFt0ILA6D6XRRm1" : {
"-MsKNnZQJNBVNdusyFax" : {
"message" : "hello ahmed",
"timestamp" : 1641036308698
}
},
"nullWtO1EJijSfgeF9JsVsMG7ZOSbjP2" : {
"-MsKNk-6YSAToqGxhD9O" : {
"message" : "hi maha",
"timestamp" : 1641036294080
},
"-MsdBSYC9LlNfrcaETS2" : {
"message" : "please",
"timestamp" : 1641368615680
}
}
}
}
public class MessageModel {
String uId, message, messageId;
Long timestamp;
public MessageModel(String uId, String message, Long timestamp) {
this.uId = uId;
this.message = message;
this.timestamp = timestamp;
}
public MessageModel(String uId, String message) {
this.uId = uId;
this.message = message;
}
public MessageModel(){
}
public String getuId() {
return uId;
}
public void setuId(String uId) {
this.uId = uId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}
public class ChatAdapter extends RecyclerView.Adapter {
ArrayList<MessageModel> messageModels;
Context context;
String recId;
int SENDER_VIEW_TYPE = 1;
int RECEIVER_VIEW_TYPE = 2;
public ChatAdapter(ArrayList<MessageModel> messageModels, Context context) {
this.messageModels = messageModels;
this.context = context;
}
public ChatAdapter(ArrayList<MessageModel> messageModels, Context context, String recId) {
this.messageModels = messageModels;
this.context = context;
this.recId = recId;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == SENDER_VIEW_TYPE)
{
View view = LayoutInflater.from(context).inflate(R.layout.sample_sender,parent,false);
return new SenderViewHolder(view);
}
else
{
View view = LayoutInflater.from(context).inflate(R.layout.sample_receiver,parent,false);
return new ReceiverViewHolder(view);
}
}
#Override
public int getItemViewType(int position) {
if(messageModels.get(position).getuId() == (FirebaseAuth.getInstance().getUid()))
{
return SENDER_VIEW_TYPE;
}
else
{
return RECEIVER_VIEW_TYPE;
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel messageModel = messageModels.get(position);
if (holder.getClass() == SenderViewHolder.class)
{
SenderViewHolder viewHolder = (SenderViewHolder) holder;
viewHolder.senderMsg.setText(messageModel.getMessage());
}
else
{
ReceiverViewHolder viewHolder = (ReceiverViewHolder) holder;
viewHolder.receiverMsg.setText(messageModel.getMessage());
}
}
#Override
public int getItemCount() {
return messageModels.size();
}
public class ReceiverViewHolder extends RecyclerView.ViewHolder{
TextView receiverMsg, receiverTime;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
receiverMsg = itemView.findViewById(R.id.receiverText);
receiverTime = itemView.findViewById(R.id.receiverTime);
}
}
public class SenderViewHolder extends RecyclerView.ViewHolder{
TextView senderMsg, senderTime;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
senderMsg = itemView.findViewById(R.id.receiverText);
senderTime = itemView.findViewById(R.id.senderTime);
}
}
}
public class ChatDetailActivity extends AppCompatActivity {
ActivityChatDetailBinding binding;
FirebaseDatabase database;
FirebaseAuth auth;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityChatDetailBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
getSupportActionBar().hide();
database = FirebaseDatabase.getInstance();
auth = FirebaseAuth.getInstance();
final String senderId = auth.getUid();
String recieveId = getIntent().getStringExtra("userId");
String userName = getIntent().getStringExtra("userName");
String profilePic = getIntent().getStringExtra("profilePic");
binding.userName.setText(userName);
Picasso.get().load(profilePic).placeholder(R.drawable.ic_avatar).into(binding.profileImage);
binding.backArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(ChatDetailActivity.this, MainActivity.class);
startActivity(intent);
}
});
final ArrayList<MessageModel> messageModels = new ArrayList<>();
final ChatAdapter chatAdapter = new ChatAdapter(messageModels,this,recieveId);
binding.chatRecyclerView.setAdapter(chatAdapter);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
binding.chatRecyclerView.setLayoutManager(layoutManager);
final String senderRoom = senderId + recieveId;
final String receiverRoom = recieveId + senderId;
binding.send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message = binding.enterMessage.getText().toString();
final MessageModel model = new MessageModel(senderId, message);
model.setTimestamp(new Date().getTime());
binding.enterMessage.setText("");
database.getReference().child("chats")
.child(senderRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
database.getReference().child("chats")
.child(receiverRoom)
.push()
.setValue(model).addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
}
});
}
});
}
});
}
}

Replace
public class ReceiverViewHolder extends RecyclerView.ViewHolder{
TextView receiverMsg, receiverTime;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
receiverMsg = itemView.findViewById(R.id.receiverText);
receiverTime = itemView.findViewById(R.id.receiverTime);
}
}
with
public class ReceiverViewHolder extends RecyclerView.ViewHolder{
TextView receiverMsg, receiverTime;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
receiverMsg = itemView.findViewById(R.id.receiverText);
receiverTime = itemView.findViewById(R.id.receiverTime);
}
public void setData(MessageModel messageModel){
viewHolder.receiverMsg.setText(messageModel.getMessage());
}
}
and replace
public class SenderViewHolder extends RecyclerView.ViewHolder{
TextView senderMsg, senderTime;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
senderMsg = itemView.findViewById(R.id.receiverText);
senderTime = itemView.findViewById(R.id.senderTime);
}
}
with
public class SenderViewHolder extends RecyclerView.ViewHolder{
TextView senderMsg, senderTime;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
senderMsg = itemView.findViewById(R.id.receiverText);
senderTime = itemView.findViewById(R.id.senderTime);
}
public void setData(MessageModel messageModel){
viewHolder.receiverMsg.setText(messageModel.getMessage());
}
}
and then finally replace your onBindViewHolder with
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel messageModel = messageModels.get(position);
if (getItemViewType(position) == SENDER_VIEW_TYPE) ((SenderViewHolder) holder).setData(messageModel);
else ((ReceiverViewHolder) holder).setData(messageModel);
}
I am not sure if it will help, but it surely will optimise your code.

Related

Failed to convert a value of type java.lang.String to int (in explore_fragment)

Showing error on getValue(User.class) in explore_fragment.
My explore_fragment is:
public class exploreFragment extends Fragment {
FragmentExploreBinding binding;
ArrayList<User> list = new ArrayList<>();
FirebaseAuth auth;
FirebaseDatabase database;
public exploreFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
auth = FirebaseAuth.getInstance();
database= FirebaseDatabase.getInstance();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding= FragmentExploreBinding.inflate(inflater, container, false);
UserAdapter adapter = new UserAdapter(getContext(),list);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
binding.usersRV.setLayoutManager(layoutManager);
binding.usersRV.setAdapter(adapter);
database.getReference().child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
User user = dataSnapshot.getValue(User.class);
user.setUserID(dataSnapshot.getKey());
if(!dataSnapshot.getKey().equals(FirebaseAuth.getInstance().getUid())){
list.add(user);
}
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
return binding.getRoot();
}
}
User_model is:
public class User {
private String name, profession,email,password,cname;
private String profile;
private String userReff;
private int guidedCount;
private String userID;
private String coverPhoto;
public User() {
}
public int getGuidedCount() {
return guidedCount;
}
public void setGuidedCount(int guidedCount) {
this.guidedCount = guidedCount;
}
public String getCoverPhoto() {
return coverPhoto;
}
public void setCoverPhoto(String coverPhoto) {
this.coverPhoto = coverPhoto;
}
public User(String name, String profession, String email, String password, String cname) {
this.name = name;
this.profession = profession;
this.email = email;
this.password = password;
this.cname = cname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProfession() {
return profession;
}
public void setProfession(String profession) {
this.profession = profession;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getUserReff() {
return userReff;
}
public void setUserReff(String userReff) {
this.userReff = userReff;
}
public String getUserID() {
return userID;
}
public void setUserID(String userID) {
this.userID = userID;
}
}
User_adapter is:
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.viewHolder>{
Context context;
ArrayList<User> list;
public UserAdapter(Context context, ArrayList<User> list) {
this.context = context;
this.list = list;
}
#NonNull
#Override
public viewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.user_sample,parent,false);
return new viewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull viewHolder holder, int position) {
User user = list.get(position);
Picasso.get().load(user.getProfile()).placeholder(R.drawable.placeholder).into(holder.binding.profileImage);
holder.binding.name.setText(user.getName());
holder.binding.profession.setText(user.getProfession());
holder.binding.viewprofilebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view){
String visiter = list.get(holder.getAdapterPosition()).getUserID();
Intent intent= new Intent(context, VActivity.class);
intent.putExtra("usersid",visiter).toString();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return list.size();
}
public class viewHolder extends RecyclerView.ViewHolder{
UserSampleBinding binding;
public viewHolder(#NonNull View itemView) {
super(itemView);
binding = UserSampleBinding.bind(itemView);
}
}
}
Error i am getting is:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.guided_app, PID: 2744
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertInteger(CustomClassMapper.java:364)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToPrimitive(CustomClassMapper.java:290)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:215)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
at com.example.guided_app.fragment.exploreFragment$1.onDataChange(exploreFragment.java:60)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
The firebase database is:
"Users": {
"59fLuGGNugPcgp6b725cFnKIzKC2": {
"cname": "LIT",
"email": "Stephen#gmail.com",
"guidedCount": 0,
"name": "Stephen Wade",
"password": "123456",
"profession": "Developer # Adobe"
},
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"cname": "BIT",
"email": "anshul#gmail.com",
"guided": {
"FOQEVbKRpNYjfzAJCp1XQtnvRlh2": {
"guidedAt": 1670152487063,
"guidedBy": "FOQEVbKRpNYjfzAJCp1XQtnvRlh2"
},
"y3pV1GhdLqOnteMO64U2F4o8mMu2": {
"guidedAt": 1670151228825,
"guidedBy": "y3pV1GhdLqOnteMO64U2F4o8mMu2"
}
},
"guidedCount": 2,
"name": "Anshul Lanjewar",
"password": "123456",
"profession": "SDE # Google"
},
"FOQEVbKRpNYjfzAJCp1XQtnvRlh2": {
"cname": "SIT",
"email": "Tanvi#gmail.com",
"guidedCount": 0,
"name": "Tanvi Colson",
"password": "123456",
"profession": "Analyst # Google"
},
"Jj2RH3iopgdLU6AC3VKeeaMKAXx1": {
"cname": "PIT",
"email": "Shana#gmail.com",
"guidedCount": 0,
"name": "Shana Sharma",
"password": "123456",
"profession": "FullStack # Netflix"
},
"gAzcrP1IYmQI0ht4qfH9WGt9U7F2": {
"cname": "MIT",
"email": "John#gmail.com",
"guided": {
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"guidedAt": 1670614050015,
"guidedBy": "7kpNGqcHeBfNqf8GrVK2Hpew0L62"
}
},
"guidedCount": "gAzcrP1IYmQI0ht4qfH9WGt9U7F2",
"name": "John Adams",
"password": "123456",
"profession": "Developer # Apple"
},
"y3pV1GhdLqOnteMO64U2F4o8mMu2": {
"cname": "BIT",
"email": "kumar#gmail.com",
"guided": {
"7kpNGqcHeBfNqf8GrVK2Hpew0L62": {
"guidedAt": 1670154254299,
"guidedBy": "7kpNGqcHeBfNqf8GrVK2Hpew0L62"
}
},
"guidedCount": 1,
"name": "Kumar Mishra",
"password": "123456",
"profession": "SDE # Microsoft"
}
}
I recently started with android development, so was just stucked.
I want to create an explore_fragment in which list of users is added in recyclerView and with view_profile button we can view user profile.
As expected, the following error:
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to int
Arrives due to the fact that an int-type field holds a value of type String. So when deserializing, the guidedCount field is expected to hold a value of type int and not String, hence the error. The node that is responsible for the Exception is:
"guidedCount": "gAzcrP1IYmQI0ht4qfH9WGt9U7F2",
See, it holds a UID rather than a number. So to solve this, change that UID with a number.

Android Java - Parse Array Entry of JSON into Recycler View

I am trying to parse a Block of JSON into a RecyclerView. So far I was able to achieve this with a quite flat JSON Structure. But now I have an Array-Entry in my JSON File where I always want to get the first Entry.
The JSON looks like this:
[
{
"MatchID": 60989,
"Team1": {
"TeamName": "FC Bayern München",
"TeamIconUrl": "https://i.imgur.com/jJEsJrj.png"
},
"Team2": {
"TeamName": "VfL Wolfsburg",
"TeamIconUrl": "https://i.imgur.com/ucqKV4B.png"
},
"MatchResults": [
{
"PointsTeam1": 4,
"PointsTeam2": 0,
"ResultOrderID": 1
},
{
"PointsTeam1": 1,
"PointsTeam2": 0,
"ResultOrderID": 2
}
]
},
{
"MatchID": 60990,
"Team1": {
"TeamName": "VfL Bochum",
"TeamIconUrl": "https://i.imgur.com/5jy3Gfr.png"
},
"Team2": {
"TeamName": "1. FC Union Berlin",
"TeamIconUrl": "https://upload.wikimedia.org/wikipedia/commons/4/44/1._FC_Union_Berlin_Logo.svg"
},
"MatchResults": [
{
"PointsTeam1": 0,
"PointsTeam2": 1,
"ResultOrderID": 1
},
{
"PointsTeam1": 0,
"PointsTeam2": 1,
"ResultOrderID": 2
}
]
}
]
My Activity fetches this JSON from an API using Retrofit2
private void parseJson() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://www.openligadb.de/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface request = retrofit.create(RequestInterface.class);
Call<List<Match>> call=request.getMatchJson();
call.enqueue(new Callback<List<Match>>() {
#Override
public void onResponse(Call<List<Match>> call, Response<List<Match>> response) {
if (response.isSuccessful() && response.body() != null) {
matchList = new ArrayList<>(response.body());
matchAdapter = new MatchAdapter(matchList, ActivityMatch.this);
mRecyclerView.setAdapter(matchAdapter);
}
}
#Override
public void onFailure(Call<List<Match>> call, Throwable t) {
Log.println(Log.ERROR, "FAILED", String.valueOf(t));
Toast.makeText(ActivityMatch.this, "Oops! Somehting went wrong!", Toast.LENGTH_SHORT).show();
}
});
}
My MatchAdapter is then parsing this Data for the View. Here I want to display whatever is the first in MatchResults then using PointsTeam1 and PointsTeam2 to display something like "4 : 0"
Now in my ModelClass accessing direct Values like the TeamName and TeamIconUrl worked but I am struggeling to get to the first entry of the Array and am really stuck on even how to properly approach this issue.
The Adapter Class:
public class MatchAdapter extends RecyclerView.Adapter<MatchAdapter.MatchHolder>{
private ArrayList<Match> matchList;
private Context context;
public MatchAdapter(ArrayList<Match> matchList, Context context) {
this.context = context;
this.matchList = matchList;
}
#NonNull
#Override
public MatchAdapter.MatchHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.match_list_row_layout, viewGroup, false);
return new MatchHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MatchAdapter.MatchHolder holder, int position) {
holder.tvTeam1name.setText(matchList.get(position).Team1.TeamName);
holder.tvTeam2name.setText(matchList.get(position).Team2.TeamName);
Glide.with(context).load(matchList.get(position).Team1.TeamIconUrl).into(holder.ivTeam1Logo);
Glide.with(context).load(matchList.get(position).Team2.TeamIconUrl).into(holder.ivTeam2Logo);
//This is not working
holder.tvResult.setText(matchList.get(position).MatchResults.PointsTeam1 + " : " + matchList.get(position).MatchResults.PointsTeam2);
}
#Override
public int getItemCount() {
return matchList.size();
}
public class MatchHolder extends RecyclerView.ViewHolder {
private TextView tvTeam1name, tvTeam2name, tvResult;
private ImageView ivTeam1Logo, ivTeam2Logo;
public MatchHolder(#NonNull View itemView) {
super(itemView);
tvTeam1name = itemView.findViewById(R.id.tv_team1name);
tvTeam2name = itemView.findViewById(R.id.tv_team2name);
tvResult = itemView.findViewById(R.id.tv_result);
ivTeam1Logo = itemView.findViewById(R.id.iv_team1logo);
ivTeam2Logo = itemView.findViewById(R.id.iv_team2logo);
}
}
}
My ModelClass (Left out Getters/Setters for Readability)
package de.eahjena.app.wi.fussball;
public class Match {
Team Team1;
Team Team2;
MatchResults MatchResults;
public Match(Team Team1, Team Team2, MatchResults MatchResults) {
this.Team1 = Team1;
this.Team2 = Team2;
this.MatchResults = MatchResults;
}
}
class Team {
String TeamName;
String TeamIconUrl;
public Team (String TeamName, String TeamIconUrl) {
this.TeamName = TeamName;
this.TeamIconUrl = TeamIconUrl;
}
}
class MatchResults {
String PointsTeam1;
String PointsTeam2;
public MatchResults(String PointsTeam1, String PointsTeam2) {
this.PointsTeam1 = PointsTeam1;
this.PointsTeam2 = PointsTeam2;
}
}
As per the question you are suppose to use List<MatchResults> MatchResults since the API response contains a list of match results.
Further to use the first position from the matchResults array you cna use it like this in your adapter :
matchList.get(position).MatchResults.get(0).PointsTeam1

How to retrieve firebase realtime database to listview inside listview and nested data?

I am currently struggling with searching references code on how to retrieve data from firebase to a listview inside a listview for Java, Android Studio. Actually, I was already successful in retrieving data from the main listview like this and into the detail when I clicked the listview:
[![main listview][1]][1]
[![detail activity and detail listview][2]][2]
So the "Nama Pemesan", "Tanggal Masuk" and so on is already successfully retrieve from firebase, except the listview of "Pesanan", "Kuantitas", and "Total Harga", I don't have any idea to retrieve it.
This are the code that I already use on the list transaksi page:
public class ListTransaksiActivity extends AppCompatActivity {
private DatabaseReference databaseReference;
private ListView listViewTransaksi;
ArrayList<Transaksi> trksArrayList = new ArrayList<>();
TransaksiAdapter transaksiAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_transaksi);
transaksiAdapter = new TransaksiAdapter(ListTransaksiActivity.this, R.layout.list_transaksi, trksArrayList);
databaseReference = FirebaseDatabase.getInstance("https://rewanglaundry-ec6e9-default-rtdb.asia-southeast1.firebasedatabase.app/").getReference("Laundry");
listViewTransaksi = findViewById(R.id.listView_Transaksi);
listViewTransaksi.setAdapter(transaksiAdapter);
databaseReference.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
Transaksi value = dataSnapshot.getValue(Transaksi.class);
trksArrayList.add(value);
transaksiAdapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
transaksiAdapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
and also the adapter for listview list transaksi:
public class TransaksiAdapter extends ArrayAdapter<Transaksi> {
public TransaksiAdapter(Context context, int layout, ArrayList<Transaksi> transaksiArrayList){
super (context, R.layout.list_transaksi, transaksiArrayList);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
row = LayoutInflater.from(getContext()).inflate(R.layout.list_transaksi, parent, false);
Transaksi currentTransaksi = getItem(position);
TextView txtTglMasuk = (TextView) row.findViewById(R.id.detail_tgl_masuk);
txtTglMasuk.setText(currentTransaksi.getTglMasuk());
TextView txtTglKeluar = (TextView) row.findViewById(R.id.detail_tgl_keluar);
txtTglKeluar.setText(currentTransaksi.getTglSelesai());
TextView txtPemesan = (TextView) row.findViewById(R.id.detail_pemesan);
txtPemesan.setText(currentTransaksi.getNamaPemesan());
TextView txtPenerima = (TextView) row.findViewById(R.id.detail_penerima);
txtPenerima.setText(currentTransaksi.getNamaPenerima());
row.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//OPEN DETAIL
openDetailActivity(currentTransaksi.getNamaPemesan(),currentTransaksi.getNamaPenerima(),currentTransaksi.getTglMasuk(), currentTransaksi.getTglSelesai(),
currentTransaksi.getTotalHarga());
}
});
}
return row;
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(getContext(),DetailAdminActivity.class);
i.putExtra("namaPemesan",details[0]);
i.putExtra("namaPenerima",details[1]);
i.putExtra("tglMasuk",details[2]);
i.putExtra("tglSelesai",details[3]);
i.putExtra("totalHarga",details[4]);
getContext().startActivity(i);
}
}
And the model:
public class Transaksi {
private String namaPemesan;
private String tglMasuk;
private String tglSelesai;
private String namaPenerima;
private String totalHarga;
public String getTotalHarga() {
return totalHarga;
}
public void setTotalHarga(String totalHarga) {
this.totalHarga = totalHarga;
}
public List<Transaksi> getTransaksiList() {
return transaksiList;
}
public void setTransaksiList(List<Transaksi> transaksiList) {
this.transaksiList = transaksiList;
}
private List<Transaksi> transaksiList;
public String getNamaPemesan() {
return namaPemesan;
}
public void setNamaPemesan(String namaPemesan) {
this.namaPemesan = namaPemesan;
}
public String getTglMasuk() {
return tglMasuk;
}
public void setTglMasuk(String tglMasuk) {
this.tglMasuk = tglMasuk;
}
public String getTglSelesai() {
return tglSelesai;
}
public void setTglSelesai(String tglSelesai) {
this.tglSelesai = tglSelesai;
}
public String getNamaPenerima() {
return namaPenerima;
}
public void setNamaPenerima(String namaPenerima) {
this.namaPenerima = namaPenerima;
}
}
And this is the firebase realtime database structure, i want to put "keranjang" data on the listview detail:
{
"Laundry" : {
"1626021441819" : {
"keranjang" : [ {
"harga" : "10000",
"id" : 13,
"namaJenis" : "KILOAN GOSOK",
"quantity" : "2"
}, {
"harga" : "9000",
"id" : 14,
"namaJenis" : "KILOAN CUCI",
"quantity" : "2"
}, {
"harga" : "5000",
"id" : 15,
"namaJenis" : "KILOAN GOSOK",
"quantity" : "1"
} ],
"namaPemesan" : "Jumi",
"namaPenerima" : "Ten",
"tglMasuk" : "11-07-2021",
"tglSelesai" : "14-07-2021",
"totalHarga" : "24000"
},
"1626264517918" : {
"keranjang" : [ {
"harga" : "8000",
"id" : 16,
"namaJenis" : "KAOS",
"quantity" : "1"
}, {
"harga" : "9000",
"id" : 17,
"namaJenis" : "KILOAN CUCI",
"quantity" : "2"
} ],
"namaPemesan" : "Toni",
"namaPenerima" : "Tuki",
"tglMasuk" : "07-07-2021",
"tglSelesai" : "10-07-2021",
"totalHarga" : "17000"
}
}
}
Do you guys have any idea where i can get a reference code to retrieve listview inside listview or something like that? Any help is appreciated. Thankyouu
[1]: https://i.stack.imgur.com/zeFpU.png
[2]: https://i.stack.imgur.com/zMykE.png

My app was working perfectly but now it keeps crashing

I'm using YouTube Data API v3 for searching YouTube videos on my app.
Last night was working perfectly but now it keeps crashing when I click search button. Can someone help me?
I've tried to regenerate API key but same error
when I change to: return mVideoList.size();
Error is: E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.youtubeexampleproject, PID: 7031
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference at
YoutubeAdapter.getItemCount(YoutubeAdapter.java:108) the pointer goes to : return mVideolist.size();
and for code below error is:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"location" : "fields",
"locationType" : "parameter",
"message" : "Invalid field selection activity",
"reason" : "invalidParameter"
} ],
"message" : "Invalid field selection activity"
}
'
query = youtube.search().list("id,snippet");
query.setKey(KEY);
query.setType("video");
query.setFields("items(id/kind,id/videoId,snippet/title,snippet/description,snippet/thumbnails/high/url/activity)");
} catch (IOException e) {
Log.d("YC", "Could not initialize: " + e);
}
}
public List<VideoItem> search(String keywords) {
query.setQ(keywords);
query.setMaxResults(MAXRESULTS);
try {
SearchListResponse response = query.execute();
List<SearchResult> results = response.getItems();
List<VideoItem> items = new ArrayList<VideoItem>();
if (results != null) {
items = setItemsList(results.iterator());
}
return items;
public class YoutubeAdapter extends RecyclerView.Adapter {
private Context mContext;
private List<VideoItem> mVideoList;
public class MyViewHolder extends RecyclerView.ViewHolder{
public ImageView thumbnail;
public TextView video_title, video_id, video_description;
public RelativeLayout video_view;
public MyViewHolder(View view) {
super(view);
thumbnail = view.findViewById(R.id.video_thumbnail);
video_title = view.findViewById(R.id.video_title);
video_id = view.findViewById(R.id.video_id);
video_description = view.findViewById(R.id.video_description);
video_view = view.findViewById(R.id.video_view);
}
}
public YoutubeAdapter(Context mContext, List<VideoItem> mVideoList) {
this.mContext = mContext;
this.mVideoList = mVideoList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.video_item, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final VideoItem singleVideo = mVideoList.get(position);
holder.video_id.setText("Video ID : "+singleVideo.getId()+" ");
holder.video_title.setText(singleVideo.getTitle());
holder.video_description.setText(singleVideo.getDescription());
Picasso.get()
.load(singleVideo.getThumbnailURL()).resize(480,270)
.centerCrop()
.into(holder.thumbnail);
holder.video_view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClass(mContext, PlayerActivity.class);
intent.putExtra("VIDEO_ID", singleVideo.getId());
intent.putExtra("VIDEO_TITLE",singleVideo.getTitle());
intent.putExtra("VIDEO_DESC",singleVideo.getDescription());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return mVideoList == null ? 0 : mVideoList.size();
}
}'
Remove snippet/thumbnails/high/url/activity from fields and try
query.setFields("items(id/kind,id/videoId,snippet/title,snippet/description)");

Get firebase database records to RecyclerView

I'm recently learning about firebase database. Now I'm trying to put the records to RecyclerView
Here is what I do
BiodataModel value;
DatabaseReference mdatabase;
private List<BiodataModel> mBiodata;
BiodataAdapter dAdapter;
List<BiodataModel> userlist = new ArrayList<>();
mdatabase = FirebaseDatabase.getInstance().getReference().child("Biodata");
mdatabase.keepSynced(true);
mdatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
userlist = new ArrayList<>();
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
BiodataModel bioModel = postSnapshot.getValue(BiodataModel.class); // The problem is here
userlist.add(bioModel);
}
} catch (Exception ex) {
Log.e("MYERROR", ex.getMessage());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("MYERROR", databaseError.getMessage());
}
});
Here is my adapter
public class BiodataAdapter extends RecyclerView.Adapter<BiodataAdapter.MyViewHolder>{
private List<BiodataModel> bioList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView fullname;
public MyViewHolder(View view) {
super(view);
fullname = (TextView) view.findViewById(R.id.fullname);
}
}
public BiodataAdapter(){
}
public BiodataAdapter(List<BiodataModel> bioList) {
this.bioList = bioList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.biodata_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
BiodataModel bio = bioList.get(position);
holder.fullname.setText(bio.getFullname());
}
#Override
public int getItemCount() {
return bioList.size();
}
}
and this is my Model
public class BiodataModel {
public String fullname,email,noTelp,alamat;
public BiodataModel(String fullname, String email, String noTelp,String alamat){
this.fullname = fullname;
this.email = email;
this.noTelp = noTelp;
this.alamat = alamat;
}
public String getFullname() {
return fullname;
}
public String getEmail() {
return email;
}
public String getNoTelp() {
return noTelp;
}
public String getAlamat() {
return alamat;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public void setEmail(String email) {
this.email = email;
}
public void setNoTelp(String noTelp) {
this.noTelp = noTelp;
}
public void setAlamat(String alamat) {
this.alamat = alamat;
}
}
and i get this error
Can't convert object of type java.lang.String to type
ZZZZ.BiodataModel
how can i fix it ?
Your reference is this:
mdatabase = FirebaseDatabase.getInstance().getReference().child("Biodata");
so at child Biodata, then you are iterating inside it's direct child for (DataSnapshot postSnapshot : dataSnapshot.getChildren()), thus retrieving the Strings Alamat,Email.
To solve this, you need to remove the for loop and try the following:
mdatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
userlist = new ArrayList<>();
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try {
BiodataModel bioModel = dataSnapshot.getValue(BiodataModel.class);
userlist.add(bioModel);
} catch (Exception ex) {
Log.e("MYERROR", ex.getMessage());
}
}
}

Categories