0

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.

Mario
  • 15
  • 6
  • I m not finding it on the (⠇) it only allow me to remove the data where is it?. Did you need to know the type of data? – Mario Sep 23 '22 at 08:50
  • I have found the import export section but it is empty – Mario Sep 23 '22 at 08:59
  • Oh, it's Firestore, then please edit your question and add your database structure as a screenshot. – Alex Mamo Sep 23 '22 at 09:22
  • done lemme know if you need more information – Mario Sep 23 '22 at 10:06
  • Are you sure that all documents have a `timestamp` field of type Timestamp and not a `long` value? Besides that, inside the class, the `timestamp` property should be Date, as explained [here](https://stackoverflow.com/questions/48474957/servertimestamp-is-allways-null-on-firebase-firestore/48475027), right? – Alex Mamo Sep 23 '22 at 10:13
  • i dont think i have understood the question... they are all strings except for timestamp – Mario Sep 23 '22 at 12:18
  • In the screenshot that you have provided, the timestamp field holds a Timestamp object. Are you sure that all documents follow the same rule? It's possible that one document to have a long rather than a timestamp. Did you understand now? – Alex Mamo Sep 23 '22 at 12:32
  • There is a long in the last lines of mainActivity but in the firestore database there is no long value maybe i can add other parts of the code like Startpage.java and SaveState.java if you think could be helpful – Mario Sep 23 '22 at 13:07
  • It's not about the code, it's about what you have in the database. – Alex Mamo Sep 23 '22 at 14:05
  • chat_image is a string message is a string message id is a string timestamp is a timestamp user_image_url is a string user_name is a string – Mario Sep 23 '22 at 14:19

0 Answers0