Hi I'm following this video tutorial https://www.youtube.com/watch?v=wQN2eCO-M_Q&t=7717s (the part I suppose create this issue can be found at time 2:01:17)and I managed to make this code work without implementing the notifications, but it only works on the simulator. When I try to debug it with my phone it gives me the following error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.chat, PID: 7894
java.lang.RuntimeException: Could not deserialize object. Failed to convert value of type java.lang.Long to Timestamp (found in field 'timestamp')
On others real devices it works properly but on my real me 8 pro it does not here is some code from my android studio:
ChatModel.java
package com.example.chat.model;
import com.google.firebase.Timestamp;
import java.sql.Time;
import java.util.Date;
public class ChatModel {
String message;
String user_name;
String messageID;
String user_image_url;
String chat_image;
Timestamp timestamp;
public ChatModel() {
}
public ChatModel(String message, String user_name, String messageID, String user_image_url, String chat_image, Timestamp timestamp) {
this.message = message;
this.user_name = user_name;
this.messageID = messageID;
this.user_image_url = user_image_url;
this.chat_image = chat_image;
this.timestamp = timestamp;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUser_name() {
return user_name;
}
public void setUser_name(String user_name) {
this.user_name = user_name;
}
public String getMessageID() {
return messageID;
}
public void setMessageID(String messageID) {
this.messageID = messageID;
}
public String getUser_image_url() {
return user_image_url;
}
public void setUser_image_url(String user_image_url) {
this.user_image_url = user_image_url;
}
public String getChat_image() {
return chat_image;
}
public void setChat_image(String chat_image) {
this.chat_image = chat_image;
}
public Timestamp getTimestamp() {
return timestamp;
}
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
}
i have tried to change Timestamp with: long, Long, Date and Number. But i wouldn't work anyways MainActivity.java
package com.example.chat;
import static com.example.chat.cords.FirebaseCords.MAIN_CHAT_DATABASE;
import static com.example.chat.cords.FirebaseCords.mAuth;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.chat.adapter.ChatAdapter;
import com.example.chat.cords.FirebaseCords;
import com.example.chat.model.ChatModel;
import com.example.chat.model.SaveState;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.Query;
import com.theartofdev.edmodo.cropper.CropImage;
import com.theartofdev.edmodo.cropper.CropImageView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Queue;
public class MainActivity extends AppCompatActivity {
@Override
public void onStart() {
super.onStart();
// Check if user is signed in (non-null) and update UI accordingly.
FirebaseUser currentUser = mAuth.getCurrentUser();
if (currentUser == null) {
startActivity(new Intent(this, LoginActivity.class));
finish();
}
chatAdapter.startListening();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.chat_room, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.logout:
mAuth.signOut();
startActivity((new Intent(this, LoginActivity.class)));
break;
}
return super.onOptionsItemSelected(item);
}
EditText chat_box;
RecyclerView chat_list;
ChatAdapter chatAdapter;
Uri imageUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chat_box = findViewById(R.id.chat_box);
chat_list = findViewById(R.id.chat_list);
initChatList();
}
private void initChatList() {
chat_list.setHasFixedSize(true);
chat_list.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, true));
Query query = MAIN_CHAT_DATABASE.orderBy("timestamp", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<ChatModel> option = new FirestoreRecyclerOptions.Builder<ChatModel>()
.setQuery(query, ChatModel.class)
.build();
chatAdapter = new ChatAdapter(option);
chat_list.setAdapter(chatAdapter);
chatAdapter.startListening();
}
public void addMessage(View view) {
String message = chat_box.getText().toString();
FirebaseUser user = mAuth.getCurrentUser();
if (!TextUtils.isEmpty(message)) {
/*Generate messageID using the current date. */
Date today = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String messageID = format.format(today);
/*Getting user image from Google account*/
String user_image_url = "";
Uri photoUrl = user.getPhotoUrl();
String originalUrl = "s96-c/photo.jpg";
String resizeImageUrl = "s400-c/photo.jpg";
if (photoUrl!=null) {
String photoPath = photoUrl.toString();
user_image_url = photoPath.replace(originalUrl,resizeImageUrl);
}
HashMap<String, Object> messageObj = new HashMap<>();
messageObj.put("message", message);
messageObj.put("user_name", user.getDisplayName());
messageObj.put("timestamp",FieldValue.serverTimestamp());
messageObj.put("messageID", messageID);
messageObj.put("chat_image","");
messageObj.put("user_image_url", user_image_url);
MAIN_CHAT_DATABASE.document(messageID).set(messageObj).addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
Toast.makeText(MainActivity.this, "Message send", Toast.LENGTH_SHORT).show();
chat_box.setText("");
} else {
Toast.makeText(MainActivity.this, task.getException().getMessage(), Toast.LENGTH_SHORT).show();
}
}
});
}
}
public void OpenExplorer(View view) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
ChoseImage();
} else {
if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 20);
} else {
Toast.makeText(this, "Storage Permission Needed", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 20);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,@NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 20) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
ChoseImage();
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
}
}
private void ChoseImage(){
CropImage.activity()
.setGuidelines(CropImageView.Guidelines.ON)
.start(MainActivity.this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode,@Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
CropImage.ActivityResult result = CropImage.getActivityResult(data);
Log.d("TAG", "onActivityResult:"+result);
if (resultCode == RESULT_OK) {
imageUri = result.getUri();
Log.d("TAG", "onActivityResult:"+imageUri);
startActivity(new Intent(MainActivity.this, ImageUploadPreview.class)
.putExtra("image_uri", imageUri.toString()));
} else if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_RESULT_ERROR_CODE) {
Toast.makeText(this, result.getError().getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
public void Finish(View view) {
long currentTime = new Date().getTime();
new SaveState(this).setClickTime(currentTime);
finish();
}
}
ChatAdapter.java
package com.example.chat.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.chat.R;
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
import com.example.chat.model.ChatModel;
import org.w3c.dom.Text;
import de.hdodenhof.circleimageview.CircleImageView;
public class ChatAdapter extends FirestoreRecyclerAdapter<ChatModel, ChatAdapter.ChatViewHolder> {
public ChatAdapter (@NonNull FirestoreRecyclerOptions <ChatModel> options) {
super(options);
}
@Override
protected void onBindViewHolder (@NonNull ChatViewHolder chatViewHolder, int i, @NonNull ChatModel chatModel) {
chatViewHolder.message.setText(chatModel.getMessage());
Glide.with(chatViewHolder.user_image.getContext().getApplicationContext())
.load(chatModel.getUser_image_url())
.into(chatViewHolder.user_image);
if(!chatModel.getChat_image().equals("")){
Glide.with(chatViewHolder.chat_image.getContext().getApplicationContext())
.load(chatModel.getChat_image())
.into(chatViewHolder.chat_image);
chatViewHolder.chat_image.setVisibility(View.VISIBLE);
}else{
chatViewHolder.chat_image.setVisibility(View.GONE);
}
}
@NonNull
@Override
public ChatViewHolder onCreateViewHolder (@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_item,parent,false);
return new ChatViewHolder(v);
}
class ChatViewHolder extends RecyclerView.ViewHolder {
TextView message;
CircleImageView user_image;
ImageView chat_image;
public ChatViewHolder(@NonNull View itemView) {
super(itemView);
message = itemView.findViewById(R.id.message);
user_image = itemView.findViewById(R.id.user_image);
chat_image = itemView.findViewById(R.id.chat_image);
}
}
}
Screenshoot of thedatabase structure: here I have no idea how to solve that error can someone help me? If you need any more information comment i will add it as soon as i see the message thanks in advance.