From the log I can see that the web service correctly returns the JSON to me. But for some reason it never enters the onResponse method.
MainActivity.java
OnResponse() method in getaccesstoken() not triggered after successful response
package com.example.alexandra.instagramlogin;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.alexandra.instagramlogin.models.AuthToken;
import com.example.alexandra.instagramlogin.rest.RestClient;
import com.example.alexandra.instagramlogin.rest.services.Auth;
import com.squareup.picasso.Picasso;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity
implements AuthenticationListener {
private static final String TAG = "MainActivity";
private String token = null;
private String code = null;
private AppPreferences appPreferences = null;
private AuthenticationDialog authenticationDialog = null;
private Button button = null;
private View info = null;
AuthToken authToken = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.btn_login);
info = findViewById(R.id.info);
appPreferences = new AppPreferences(this);
//check already have access token
}
public void login() {
button.setText("LOGOUT");
info.setVisibility(View.VISIBLE);
ImageView pic = findViewById(R.id.pic);
Picasso.with(this).load(appPreferences.getString(AppPreferences.PROFILE_PIC)).into(pic);
TextView id = findViewById(R.id.id);
id.setText(appPreferences.getString(AppPreferences.USER_ID));
TextView name = findViewById(R.id.name);
name.setText(appPreferences.getString(AppPreferences.USER_NAME));
}
public void logout() {
button.setText("INSTAGRAM LOGIN");
token = null;
info.setVisibility(View.GONE);
appPreferences.clear();
}
#Override
public void onTokenReceived(String auth_code) {
Log.d(TAG, auth_code);
appPreferences.putString(AppPreferences.CODE, auth_code);
code = auth_code;
getAccessToken(code);
}
//getting access token
private void getAccessToken(final String code) {
Auth auth = RestClient.getInstance();
Call<AuthToken>authTokenCall = auth.getAuthToken(getString(R.string.client_id),getString(R.string.client_secret),"authorization_code",getString(R.string.redirect_url),
code);
authTokenCall.enqueue(new Callback<AuthToken>() {
#Override
public void onResponse(Call<AuthToken> call, Response<AuthToken> response) {
Log.d(TAG, "onResponse: ");
}
#Override
public void onFailure(Call<AuthToken> call, Throwable t) {
}
});
}
public void onClick(View view) {
if(token!=null)
{
logout();
}
else {
authenticationDialog = new AuthenticationDialog(this, this);
authenticationDialog.setCancelable(true);
authenticationDialog.show();
}
}
}
pojo(AuthToken)
package com.example.alexandra.instagramlogin.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AuthToken {
#SerializedName("access_token")
#Expose
private String access_token;
#SerializedName("user_id")
#Expose
private Integer user_id;
public String getAccessToken() {
return access_token;
}
public void setAccessToken(String accessToken) {
this.access_token = accessToken;
}
public Integer getUserId() {
return user_id;
}
public void setUserId(Integer userId) {
this.user_id = userId;
}
}
Auth.java
package com.example.alexandra.instagramlogin.rest.services;
import com.example.alexandra.instagramlogin.Classes.AuthorizationToken;
import com.example.alexandra.instagramlogin.models.AuthToken;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;
public interface Auth {
#FormUrlEncoded
#POST("oauth/access_token")
Call<AuthToken>getAuthToken(#Field("client_id")String clientid,#Field("client_secret")String client_secret,#Field("grant_type")String grant_type
,#Field("redirect_uri")String redirect_uri,#Field("code")String code);
}
Response
D/OkHttp: {"access_token": "IGQVJXWTcyNVBZANmFfeWNSQXUwQmdZAYlUtSHYxc1Q1dUlZAWTVPaTVTZA3dqYU00dC1ocjc4WDJwS2ZA2cVJjMTA3Rkx5QkN4alBlVjFNWjBndkJMcm45ZA0s3dk5HbXBFNnU5empGVGI0WXdrb1ZARZADktVlFjeVJIQUxGRnpv", "user_id": 17841401561947636}
I think you are not handling all case correctly like what if onFailure trigger for error.
I am not debugging you project so exact error i can tell you but i suggest you some links where you can find how to debug your code properly.
How to debug android apps
Related
I have a object class that I want to use it between activities.
I used exactly the same method for another activities and worked perfectly fine. But here I can't figure it out what I am doing wrong. This is the object class :
`package com.mecachrome.ffbf;
import android.os.Parcel;
import android.os.Parcelable;
public class topic implements Parcelable {
public static Creator<topic> getCREATOR() {
return CREATOR;
}
public static final Creator<topic> CREATOR = new Creator<topic>() {
#Override
public topic createFromParcel(Parcel in) {
return new topic(in);
}
#Override
public topic [] newArray(int size) {
return new topic[size];
}
};
private String name;
private String comment;
private String id;
private String username;
public topic() {
}
public topic(String name, String comment, String id, String username) {
this.name = name;
this.comment = comment;
this.id = id;
this.username = username;
}
protected topic(Parcel in) {
name = in.readString();
comment = in.readString();
id = in.readString();
username = in.readString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getComment() {
return comment;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
#Override
public String toString() {
return "topic{" +
"name='" + name + '\'' +
", comment='" + comment + '\'' +
", id='" + id + '\'' +
", username='" + username + '\'' +
'}';
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(comment);
dest.writeString(id);
dest.writeString(username);
}
}`
This is the class that I want to take the object from:
`package com.mecachrome.ffbf;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class forum extends AppCompatActivity {
RecyclerView rv_forum;
forumAdapter myadapter;
Button add_topic;
Button test;
DatabaseReference databaseref;
private ArrayList<topic> topicList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_forum);
add_topic = findViewById(R.id.btn_new_topic);
rv_forum = findViewById(R.id.rv_topics);
rv_forum.setHasFixedSize(true);
rv_forum.setLayoutManager(new LinearLayoutManager(this));
test = findViewById(R.id.test_btn);
topicList = new ArrayList<>();
databaseref = FirebaseDatabase.getInstance().getReference("forum_topics");
databaseref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dss: snapshot.getChildren()){
topic top = dss.getValue(topic.class);
topicList.add(top);
}
myadapter = new forumAdapter(forum.this, topicList, mTopic -> {
Intent intent = new Intent(forum.this, topic_chat.class);
intent.putExtra("topic",mTopic);
startActivity(intent);
});
rv_forum.setAdapter(myadapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(forum.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
add_topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(forum.this, add_new_topic.class);
startActivity(i);
}
});
}
}`
And this is the class that I want to transfer the object to:
`package com.mecachrome.ffbf;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
public class topic_chat extends AppCompatActivity {
RecyclerView rv_chat;
chatAdapter myadapter;
Button send;
TextView topic_name;
TextView chat_text;
String chat;
private topic mTopic;
private ArrayList<chat> chatList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_topic_chat);
mTopic = getIntent().getParcelableExtra("topic");
send = findViewById(R.id.btn_send_chat);
rv_chat = findViewById(R.id.rv_topics);
rv_chat.setHasFixedSize(true);
rv_chat.setLayoutManager(new LinearLayoutManager(this));
topic_name = findViewById(R.id.tv_topic_name);
chat_text = findViewById(R.id.et_comment);
chat = chat_text.getText().toString().trim();
chatList = new ArrayList<>();
DatabaseReference databaseref = FirebaseDatabase.getInstance().getReference("forum_topics").child(mTopic.getId()).child("chat");
topic_name.setText(mTopic.getName());
Calendar calendar = Calendar.getInstance();
String currentDate = DateFormat.getDateInstance(DateFormat.SHORT).format(calendar.getTime());
chatList = new ArrayList<>();
databaseref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dss: snapshot.getChildren()){
chat mess = dss.getValue(chat.class);
chatList.add(mess);
}
myadapter = new chatAdapter(topic_chat.this, chatList, chat -> {
Intent intent = new Intent(topic_chat.this, topic_chat.class);
startActivity(intent);
});
rv_chat.setAdapter(myadapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Toast.makeText(topic_chat.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
chat msg = new chat(mTopic.getName(),chat,mTopic.getId(),currentDate);
databaseref.setValue(msg).addOnCompleteListener(task1 -> {
if (task1.isSuccessful()){
Toast.makeText(topic_chat.this, "Review was been added Successfully", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(topic_chat.this, "Review failed to post. Try Again!", Toast.LENGTH_SHORT).show();
}
});;
}
});
}
}`
The object class is "topic"
The error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.mecachrome.ffbf.topic.getId()' on a null object reference
On this line
DatabaseReference databaseref = FirebaseDatabase.getInstance().getReference("forum_topics").child(mTopic.getId()).child("chat");
because mTopic.getId() is null. Any help?
I am facing this problem for the last two weeks. Can you help me why this problem occurs?
Error occur at this line allClient.callPhoneNumber("+16315192247");
Please check it. Every time it crashes.
package com.eureka.voicecallinapk;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.sinch.android.rtc.PushPair;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.calling.Call;
import com.sinch.android.rtc.calling.CallClient;
import com.sinch.android.rtc.calling.CallClientListener;
import com.sinch.android.rtc.calling.CallListener;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public static final String APP_KEY = "b7258284-f0dnd-4734-afec-210d387d****";
//i do it for security because i am posting here
public static final String APP_SECRET = "k76tOLgz+kSdKL7ULYsH**==";
public static final String ENVIRONMENT = "clientapi.sinch.com";
public Call call;
private TextView callState;
public SinchClient sinchClient;
private Button button;
private String callerId;
private String recipientId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = getIntent();
callerId = intent.getStringExtra("callerId");
recipientId = intent.getStringExtra("recipientId");
sinchClient = Sinch.getSinchClientBuilder()
.context(MainActivity.this)
.userId("172976")
.applicationKey(APP_KEY)
.applicationSecret(APP_SECRET)
.environmentHost(ENVIRONMENT)
.build();
sinchClient.setSupportCalling(true);
sinchClient.startListeningOnActiveConnection();
sinchClient.start();
// sinchClient.getCallClient().addCallClientListener(new SinchCallClientListener());
button = findViewById(R.id.button);
callState = findViewById(R.id.callState);
button.setOnClickListener(view -> {
if (call == null) {
try {
boolean s=isStarted();
Log.d("checksinch", String.valueOf(s));
CallClient callClient = sinchClient.getCallClient();
callClient.callPhoneNumber("+16315192247"); // Error occur at this line "SinchClient not started"
//callClient.callPhoneNumber("+16315192247");
// call = sinchClient.getCallClient().callPhoneNumber("+46000000000.");
// call.addCallListener(new SinchCallListener());
button.setText("Hang Up");
}catch (Exception e){
Log.d("checksinch", e.getMessage());
}
} else {
call.hangup();
button.setText("Call");
}
});
}
private boolean isStarted() {
return (sinchClient != null && sinchClient.isStarted());
}
private class SinchCallListener implements CallListener {
#Override
public void onCallEnded(Call endedCall) {
call = null;
SinchError a = endedCall.getDetails().getError();
button.setText("Call");
callState.setText("");
setVolumeControlStream(AudioManager.USE_DEFAULT_STREAM_TYPE);
}
#Override
public void onCallEstablished(Call establishedCall) {
callState.setText("connected");
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
#Override
public void onCallProgressing(Call progressingCall) {
callState.setText("ringing");
}
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
}
}
private class SinchCallClientListener implements CallClientListener {
#Override
public void onIncomingCall(CallClient callClient, Call incomingCall) {
call = incomingCall;
Toast.makeText(MainActivity.this, "incoming call", Toast.LENGTH_SHORT).show();
call.answer();
call.addCallListener(new SinchCallListener());
button.setText("Hang Up");
}
}
}
I have been trying to create a chat application and have implemented it using firestore database. The chat functionality works fine but as soon as the screen is filled and some scrolling is required to see the previous messages, the database updates in a weird way and the order becomes random and sometimes recent messages show up and sometimes older messages show up as a new message. I have used timestamp to order them but it doesn't seem to work. Even after using pagination, it didn't help. The data and order seem to change while scrolling the recycler view. I will put up the code and some screen shots for a better understanding.
Message Model.java
public class MessageModel {
String message, senderID, receiverID;
Long timestamp;
public MessageModel() {
}
public MessageModel(String senderID, String receiverID, String message, Long timestamp) {
this.senderID = senderID;
this.receiverID = receiverID;
this.message = message;
this.timestamp = timestamp;
}
public MessageModel(String senderID, String message) {
this.senderID = senderID;
this.message = message;
}
public String getReceiverID() {
return receiverID;
}
public void setReceiverID(String receiverID) {
this.receiverID = receiverID;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
public String getSenderID() {
return senderID;
}
public void setSenderID(String senderID) {
this.senderID = senderID;
}
}
Message Adapter
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.example.chatdemo.Models.MessageModel;
import com.example.chatdemo.databinding.ReceiverTextItemBinding;
import com.example.chatdemo.databinding.SenderTextItemBinding;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
public class NewMessageAdapter extends RecyclerView.Adapter {
private ReceiverTextItemBinding receiverTextItemBinding;
private SenderTextItemBinding senderTextItemBinding;
private Context context;
private FirebaseUser fUser;
private int SENDER_VIEW_TYPE = 1, RECEIVER_VIEW_TYPE = 2;
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MMM-yy KK:mm a", Locale.US);
private List<MessageModel> mMessage;
public NewMessageAdapter(Context context, List<MessageModel> mMessage) {
this.context = context;
this.mMessage = mMessage;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == SENDER_VIEW_TYPE) {
senderTextItemBinding = SenderTextItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new SenderViewHolder(senderTextItemBinding.getRoot());
} else {
receiverTextItemBinding = ReceiverTextItemBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
return new ReceiverViewHolder(receiverTextItemBinding.getRoot());
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
MessageModel messageModel = mMessage.get(position);
if (holder.getClass() == SenderViewHolder.class) {
senderTextItemBinding.tvSenderText.setText(messageModel.getMessage());
senderTextItemBinding.tvSenderTextTime.setText(simpleDateFormat
.format(new Date(Long.parseLong(messageModel.getTimestamp().toString()))));
} else {
receiverTextItemBinding.tvReceiverText.setText(messageModel.getMessage());
receiverTextItemBinding.tvReceiverTextTime.setText(simpleDateFormat
.format(new Date(Long.parseLong(messageModel.getTimestamp().toString()))));
}
}
#Override
public int getItemCount() {
return mMessage.size();
}
#Override
public int getItemViewType(int position) {
fUser = FirebaseAuth.getInstance().getCurrentUser();
if (mMessage.get(position).getSenderID().equals(fUser.getUid())) {
return SENDER_VIEW_TYPE;
} else {
return RECEIVER_VIEW_TYPE;
}
}
public class ReceiverViewHolder extends RecyclerView.ViewHolder {
private TextView receivedMessage, receivedTime;
public ReceiverViewHolder(#NonNull View itemView) {
super(itemView);
receivedMessage = receiverTextItemBinding.tvReceiverText;
receivedTime = receiverTextItemBinding.tvReceiverTextTime;
}
}
public class SenderViewHolder extends RecyclerView.ViewHolder {
private TextView sentMessage, sentTime;
public SenderViewHolder(#NonNull View itemView) {
super(itemView);
sentMessage = senderTextItemBinding.tvSenderText;
sentTime = senderTextItemBinding.tvSenderTextTime;
}
}
}
Chat Activity
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AbsListView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.chatdemo.Adapters.ChatAdapter;
import com.example.chatdemo.Adapters.NewMessageAdapter;
import com.example.chatdemo.Constants.Constants;
import com.example.chatdemo.Models.MessageModel;
import com.example.chatdemo.databinding.ActivityChatDetailBinding;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.ListenerRegistration;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
public class ChatDetailActivity extends AppCompatActivity {
private ActivityChatDetailBinding binding;
private Constants constants;
private MessageModel messageModel;
private FirebaseAuth firebaseAuth;
private FirebaseFirestore firestoreDB;
private String userID;
private FirestoreRecyclerOptions<MessageModel> options;
private ChatAdapter chatAdapter;
public static final String TAG = "paginate";
private NewMessageAdapter newMessageAdapter;
private RecyclerView recyclerView;
private List<MessageModel> mMessage;
private final int limit = 15;
private DocumentSnapshot lastVisible;
private boolean isScrolling = false;
private boolean isLastItemReached = false;
private String senderID, receiverID, receiverName, receiverPhoto;
private CollectionReference collectionReference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityChatDetailBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
firebaseAuth = FirebaseAuth.getInstance();
firestoreDB = FirebaseFirestore.getInstance();
userID = firebaseAuth.getUid();
constants = new Constants();
senderID = firebaseAuth.getUid();
receiverID = getIntent().getStringExtra("receiverID");
receiverName = getIntent().getStringExtra("receiverName");
receiverPhoto = getIntent().getStringExtra("receiverPhoto");
binding.chatUserName.setText(receiverName);
Glide.with(getApplicationContext())
.load(Uri.parse(receiverPhoto))
.into(binding.chatUserImage);
binding.btnChatBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Go back
startActivity(new Intent(ChatDetailActivity.this, MainActivity.class));
}
});
collectionReference = firestoreDB.collection(constants.getChats())
.document(userID)
.collection(constants.getMessages())
.document(receiverID)
.collection(constants.getMessages());
binding.btnSendChat.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!binding.etMessage.getText().toString().equals("")) {
String message = binding.etMessage.getText().toString().trim();
messageModel = new MessageModel(senderID, receiverID, message, new Date().getTime());
binding.etMessage.setText("");
ProgressDialog progressDialog = new ProgressDialog(ChatDetailActivity.this);
progressDialog.setMessage("Sending...");
progressDialog.show();
firestoreDB.collection(constants.getChats())
.document(userID)
.collection(constants.getMessages())
.document(receiverID)
.collection(constants.getMessages())
.add(messageModel)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
firestoreDB.collection(constants.getChats())
.document(receiverID)
.collection(constants.getMessages())
.document(userID)
.collection(constants.getMessages())
.add(messageModel)
.addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
progressDialog.dismiss();
Toast.makeText(ChatDetailActivity.this, "Message Sent", Toast.LENGTH_SHORT).show();
}
});
}
});
progressDialog.dismiss();
}
}
});
collectionReference.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
Toast.makeText(ChatDetailActivity.this, "Change", Toast.LENGTH_SHORT).show();
readMessage(userID, receiverID);
}
});
initNewRecycler();
}
private void initNewRecycler() {
recyclerView = binding.chatRecyclerView;
recyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getApplicationContext());
linearLayoutManager.setStackFromEnd(false);
linearLayoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(linearLayoutManager);
}
private void readMessage(String userID, String receiverID) {
mMessage = new ArrayList<>();
collectionReference.orderBy("timestamp", Query.Direction.DESCENDING).limit(limit)
.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
mMessage.clear();
for (QueryDocumentSnapshot snapshot : queryDocumentSnapshots) {
MessageModel model = snapshot.toObject(MessageModel.class);
if (model.getReceiverID().equals(userID) && model.getSenderID().equals(receiverID)
|| model.getReceiverID().equals(receiverID) && model.getSenderID().equals(userID)) {
mMessage.add(model);
}
newMessageAdapter = new NewMessageAdapter(ChatDetailActivity.this, mMessage);
recyclerView.setAdapter(newMessageAdapter);
}
}
});
}
}
Firebase firestore database structure
Firebase-root
|
---- chats
|
---- userID
|
---messages
|
---receiverID
|
---messages
|
---- message: "Hello!"
|
---- timestamp: 1498472455940
|
---- senderID: senderID
|
---- receiverID: receiverID
Some sample screenshots of the problem I have been facing
The first screen is what appears when the chat activity is first opened and the messages are displayed. Here everything works fine and the messaging system works.
In the second picture however we can see that when the user scrolls up to see the previous messages, some of them are shown correctly but some of them like "Does it work" and "No perhaps" have different time and some are not in the correct order. This happens frequently whenever the user scrolls the list
This is the problem I have been facing for quite a while now. I am not sure what is causing this kind of behaviour and would love to have some light shed in this issue. If anyone can help, it would be highly appreciated. Thanks.
Even though every thing is working properly and registration is happening. Retrofit on Response don't get called but onFailure gets called. Call.isexecutted returns true.
I am showing the model class and registrationFragment where the error occured. This is taking a lot time. So thanks in advance for help
RegistrationFragment.java
package com.example.milan.hospital;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple {#link Fragment} subclass.
*/
public class RegistrationFragment extends Fragment {
private EditText Name,UserName, UserPassword;
private Button BnRegister;
public RegistrationFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_registration, container, false);
Name = view.findViewById(R.id.txt_name);
UserName = view.findViewById(R.id.txt_user_name);
UserPassword = view.findViewById(R.id.txt_password);
BnRegister = view.findViewById(R.id.bn_register);
BnRegister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
performRegistration();
}
});
return view;
}
public void performRegistration()
{
String name = Name.getText().toString();
String username = UserName.getText().toString();
String password = UserPassword.getText().toString();
Call<User> call = MainActivity.apiInterface.performRegistration(name,username,password);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
if(response.body().getResponse().equals("ok"))
{
MainActivity.prefConfig.displayToast("Registration success...");
}
else if(response.body().getResponse().equals("exist"))
{
MainActivity.prefConfig.displayToast("User already exist....");
}
else if(response.body().getResponse().equals("error"))
{
MainActivity.prefConfig.displayToast("Something went wrong...");
}
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
});
Name.setText("");
UserPassword.setText("");
UserName.setText("");
}
}
User.java
package com.example.milan.hospital;
import com.google.gson.annotations.SerializedName;
public class User {
#SerializedName("response")
private String Response;
#SerializedName("name")
private String Name;
public String getResponse() {
return Response;
}
public String getName() {
return Name;
}
}
MainActivity.java
package com.example.milan.hospital;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity implements LoginFragment.OnLoginFormActivityListener{
public static PrefConfig prefConfig;
public static ApiInterface apiInterface;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prefConfig = new PrefConfig(this);
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
if(findViewById(R.id.fragment_container) != null)
{
if(savedInstanceState != null)
{
return;
}
if(prefConfig.readLoginStatus())
{
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,new WelcomeFragment()).commit();
}
else
{
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container,new LoginFragment()).commit();
}
}
}
#Override
public void performRegister() {
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new RegistrationFragment()).addToBackStack(null).commit();
}
#Override
public void performLogin(String name) {
}
}
ApiInterface.java
package com.example.milan.hospital;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface ApiInterface
{
#GET("register.php")
Call<User> performRegistration(#Query("name") String Name,#Query("user_name") String UserName,#Query("user_password") String UserPassword);
#GET("login.php")
Call<User> performUserLogin(#Query("user_name") String UserName,#Query("user_password") String UserPassword);
}
I think performRegistration() in ApiInterface.java should have an annotation of #POST rather than #GET since registration is the act of posting data rather than getting. Give it a try once.
change the ApiClient to this. As there was a well known problem of retrofit while reading json. to resolve we have initialize gson object ourself
public class ApiClient
{
public static final String BASE_URL = "http://10.0.3.2/loginapp/";
public static Retrofit retrofit = null;
public static Retrofit getApiClient()
{
Gson gson = new GsonBuilder()
.setLenient()
.create();
if(retrofit == null)
{
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create(gson)).build();
}
return retrofit;
}
}
I want the variables one, two and three to be able to read from my database when I scan the QR Code but I cant get them to display in the Builder.setMessage() line... I have tried calling the displayDeals() method in several places but none work...
package com.example.darren.offerapp;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class PopUpPage extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private ZXingScannerView mScannerView;
private FirebaseAuth firebaseAuth;
private FirebaseUser firebaseUser;
private DatabaseReference databaseReference;
private String dealID;
private Deals_Information deals_information;
private String one = "";
private String two = "";
private String three = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pop_up_page);
//stuff for popup window
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels;
int height = dm.heightPixels;
getWindow().setLayout((int)(width*0.8), (int)(height*0.6));
//calling the method which will pull the deals from the database
//displaySuggestion();
firebaseAuth = FirebaseAuth.getInstance();
firebaseUser = firebaseAuth.getCurrentUser();
databaseReference = FirebaseDatabase.getInstance().getReference();
dealID = firebaseUser.getUid();
displayDeals();
}
public void displayDeals(){
databaseReference.child("FruitDeals").child(dealID).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
deals_information = dataSnapshot.getValue(Deals_Information.class);
one = deals_information.getDeal();
two = deals_information.getPrice();
three = deals_information.getAisleNum();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
public void onClick(View v){
mScannerView = new ZXingScannerView(this);
setContentView(mScannerView);
mScannerView.setResultHandler(this);
mScannerView.startCamera();
}
#Override
protected void onPause() {
super.onPause();
mScannerView.stopCamera();
}
#Override
public void handleResult(Result result) {
//do anything with result here
Log.w("handleResult", result.getText());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Your Deal");
builder.setMessage("Offer: " + one + "\r\n\r\nPrice: " + two + "\r\n\r\nAisle Number: " + three + "");
AlertDialog alertDialog = builder.create();
alertDialog.show();
//resume scanning
//mScannerView.resumeCameraPreview(this); //uncomment out this line when you want to scan again
}
}
The Deals_Information class is here:
package com.example.darren.offerapp;
public class Deals_Information {
private String deal;
private String price;
private String aisleNum;
//getters and setters
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getAisleNum() {
return aisleNum;
}
public void setAisleNum(String aisleNum) {
this.aisleNum = aisleNum;
}
public String getDeal() {
return deal;
}
public void setDeal(String deal) {
this.deal = deal;
}
public Deals_Information(){
}
public Deals_Information(String deal, String price, String aisleNum)
{
this.deal = deal;
this.price = price;
this.aisleNum = aisleNum;
}
}
This is the image I am talking about in my last comment