简体   繁体   中英

App crashes when trying to run in background/foreground but works for other phones

While using android studio and firebase, my app (in the background or foreground) crashes on an API 26 device when notification is clicked. Whereas when I use an API 23 device, the app crashes when the app is closed and notification is clicked but can still process the notification when app is in the background/foreground. I don't understand the problem and any help is appreciated.

NOTIFICATION SERVICE

import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;

import com.google.firebase.messaging.RemoteMessage;

public class FirebaseMessagingService extends com.google.firebase.messaging.FirebaseMessagingService {


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);

        String notification_title = remoteMessage.getNotification().getTitle();
        String notification_message = remoteMessage.getNotification().getBody();

        String click_action = remoteMessage.getNotification().getClickAction();

        String from_user_id = remoteMessage.getData().get("from_user_id");

        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(FirebaseMessagingService.this, "default")
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentTitle(notification_title)
                        .setContentText(notification_message);


        Intent resultIntent = new Intent(click_action);
        resultIntent.putExtra("user_id", from_user_id);


        PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        FirebaseMessagingService.this,
                        0,
                        resultIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );

        mBuilder.setContentIntent(resultPendingIntent);




        int mNotificationId = (int) System.currentTimeMillis();

        NotificationManager mNotifyMgr =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);


        mNotifyMgr.notify(mNotificationId, mBuilder.build());


    }
}

USERS ACTIVITY

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.squareup.picasso.Picasso;

import de.hdodenhof.circleimageview.CircleImageView;


public class UsersActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private RecyclerView mUsersList;
    private DatabaseReference mUsersDatabase;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_users);
        mToolbar=(Toolbar)findViewById(R.id.users_appBar);
        setSupportActionBar(mToolbar);
        getSupportActionBar().setTitle("All Users");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        mUsersDatabase= FirebaseDatabase.getInstance().getReference().child("Users");
        mUsersDatabase.keepSynced(true);
        mUsersList=(RecyclerView)findViewById(R.id.users_list);
        mUsersList.setHasFixedSize(true);
        mUsersList.setLayoutManager(new LinearLayoutManager(this));


    }

    @Override
    protected void onStart() {
        super.onStart();
        startListening();

    }
    public void startListening(){
        Query query = FirebaseDatabase.getInstance()
                .getReference()
                .child("Users")
                .limitToLast(50);

        FirebaseRecyclerOptions<Users> options =
                new FirebaseRecyclerOptions.Builder<Users>()
                        .setQuery(query, Users.class)
                        .build();
        FirebaseRecyclerAdapter<Users, UserViewHolder> adapter = new FirebaseRecyclerAdapter<Users, UserViewHolder>(options) {

            @Override
            public UserViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                // Create a new instance of the ViewHolder, in this case we are using a custom
                // layout called R.layout.message for each item
                View view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.users_single_layout, parent, false);

                return new UserViewHolder(view);
            }

            @Override
            protected void onBindViewHolder(UserViewHolder holder, int position, Users model) {
                // Bind the Chat object to the ChatHolder
                holder.setName(model.name);
                holder.setStatus(model.status);
                holder.setUserImage(model.getThumb_image());
                final String user_id= getRef(position).getKey();

                holder.mView.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent profileIntent = new Intent(UsersActivity.this, ProfileActivity.class);
                        if (user_id != null) {
                            profileIntent.putExtra("user_id", user_id);
                            startActivity(profileIntent);
                        }
                    }
                });
            }


        };
        mUsersList.setAdapter(adapter);
        adapter.startListening();
    }

    public static class UserViewHolder extends RecyclerView.ViewHolder {
        View mView;
        public UserViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
        }
        public void setName(String name){
            TextView userNameView = (TextView) mView.findViewById(R.id.user_single_name);
            userNameView.setText(name);
        }

        public void setStatus(String status){
            TextView userStatusView= (TextView) mView.findViewById(R.id.user_single_status);
            userStatusView.setText(status);
        }

        public void setUserImage(String thumb_image){
            CircleImageView userImageView = (CircleImageView) mView.findViewById(R.id.user_single_image);
            Picasso.get().load(thumb_image).placeholder(R.drawable.accountpicture).into(userImageView);
        }

    }
}

PROFILE ACTIVITY

import android.app.ProgressDialog;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
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.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;

import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;


public class ProfileActivity extends AppCompatActivity {

    private ImageView mProfileImage;
    private TextView mProfileName, mProfileStatus, mProfileFriendsCount;
    private Button mProfileSendReqBtn;
    private DatabaseReference mUserDatabase;
    private Button declineRequest;
    private FirebaseUser mCurrent_user;
    private ProgressDialog mProgressDialog;
    private DatabaseReference mFriendRequestDatabase;
    private DatabaseReference mFriendDatabase;
    private String mCurrent_state;
    private DatabaseReference mNotificationDatabase;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_profile);
        final String user_id = getIntent().getStringExtra("user_id");
        mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(user_id);
        mFriendRequestDatabase = FirebaseDatabase.getInstance().getReference().child("Friend_req");
        mCurrent_user= FirebaseAuth.getInstance().getCurrentUser();
        mFriendDatabase= FirebaseDatabase.getInstance().getReference().child("Friends");
        mNotificationDatabase= FirebaseDatabase.getInstance().getReference().child("notifications");
        mProfileImage = (ImageView) findViewById(R.id.profile_image);
        mProfileName = (TextView) findViewById(R.id.profile_profileName);
        mProfileStatus = (TextView) findViewById(R.id.profile_status);
        mProfileFriendsCount = (TextView) findViewById(R.id.profile_totalFriends);
        mProfileSendReqBtn = (Button) findViewById(R.id.profile_send_req_btn);
        declineRequest= (Button)findViewById(R.id.profile_decline_btn);
        mCurrent_state = "not_friends";
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setTitle("Loading User Data");
        mProgressDialog.setMessage("Please wait...");
        mProgressDialog.setCanceledOnTouchOutside(false);
        mProgressDialog.show();
        mUserDatabase.keepSynced(true);
        mFriendDatabase.keepSynced(true);
        mFriendRequestDatabase.keepSynced(true);
        declineRequest.setVisibility(View.INVISIBLE);

        if(mCurrent_user.getUid().equals(user_id)){
            mProfileSendReqBtn.setVisibility(View.INVISIBLE);
        }

        mUserDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                String diplay_name = dataSnapshot.child("name").getValue().toString();
                String status = dataSnapshot.child("status").getValue().toString();
                final String image = dataSnapshot.child("image").getValue().toString();
                mProfileName.setText(diplay_name);
                mProfileStatus.setText(status);
                Picasso.get().load(image).networkPolicy(NetworkPolicy.OFFLINE).placeholder(R.drawable.accountpicture).into(mProfileImage, new Callback() {
                    @Override
                    public void onSuccess() {

                    }

                    @Override
                    public void onError(Exception e) {
                        Picasso.get().load(image).placeholder(R.drawable.accountpicture).into(mProfileImage);
                    }
                });

                mFriendRequestDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                        if(dataSnapshot.hasChild(user_id)){
                            String req_type= dataSnapshot.child(user_id).child("request_type").getValue().toString();
                            if(req_type.equals("received")){
                                mCurrent_state= "req_received";
                                mProfileSendReqBtn.setText("Accept Friend Request");
                                declineRequest.setVisibility(View.VISIBLE);
                                mUserDatabase.keepSynced(true);
                                mFriendDatabase.keepSynced(true);
                                mFriendRequestDatabase.keepSynced(true);
                            }
                            else if(req_type.equals("sent")){
                                mCurrent_state="req_sent";
                                mProfileSendReqBtn.setText("Cancel Friend Request");
                                mUserDatabase.keepSynced(true);
                                mFriendDatabase.keepSynced(true);
                                mFriendRequestDatabase.keepSynced(true);
                            }
                            else if(req_type.equals("req_sent")){
                                mCurrent_state= "not_friends";
                                mProfileSendReqBtn.setText("Send Friend Request");
                                mUserDatabase.keepSynced(true);
                                mFriendDatabase.keepSynced(true);
                                mFriendRequestDatabase.keepSynced(true);
                            }
                            mProgressDialog.dismiss();
                        }
                        else{

                            mFriendDatabase.child(mCurrent_user.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                    if(dataSnapshot.hasChild(user_id)){
                                        mCurrent_state= "friends";
                                        mProfileSendReqBtn.setText("Unfriend User");
                                        mProfileSendReqBtn.setEnabled(true);
                                        mUserDatabase.keepSynced(true);
                                        mFriendDatabase.keepSynced(true);
                                        mFriendRequestDatabase.keepSynced(true);
                                    }
                                    mProgressDialog.dismiss();
                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {
                                    mProgressDialog.dismiss();

                                }
                            });
                        }


                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {

                    }
                });


            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });



            mProfileSendReqBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mProfileSendReqBtn.setEnabled(false);
                    if (user_id.equals(mCurrent_user.getUid())) {
                        Toast.makeText(ProfileActivity.this, "Cannot send friend request to yourself!", Toast.LENGTH_LONG).show();
                        declineRequest.setVisibility(View.INVISIBLE);
                    } else {
                        if (mCurrent_state.equals("not_friends")) {
                            mFriendRequestDatabase.child(mCurrent_user.getUid()).child(user_id).child("request_type").setValue("sent").addOnCompleteListener(new OnCompleteListener<Void>() {
                                @Override
                                public void onComplete(@NonNull Task<Void> task) {
                                    if (task.isSuccessful()) {
                                        mFriendRequestDatabase.child(user_id).child(mCurrent_user.getUid()).child("request_type").setValue("received").addOnSuccessListener(new OnSuccessListener<Void>() {
                                            @Override
                                            public void onSuccess(Void aVoid) {


                                                HashMap<String, String> notificationData= new HashMap<>();
                                                notificationData.put("from", mCurrent_user.getUid());
                                                notificationData.put("type", "request");

                                                mNotificationDatabase.child(user_id).push().setValue(notificationData).addOnSuccessListener(new OnSuccessListener<Void>() {
                                                    @Override
                                                    public void onSuccess(Void aVoid) {
                                                        mCurrent_state = "req_sent";
                                                        mProfileSendReqBtn.setText("Cancel Friend Request");
                                                        mUserDatabase.keepSynced(true);
                                                        mFriendDatabase.keepSynced(true);
                                                        mFriendRequestDatabase.keepSynced(true);
                                                    }
                                                });


                                            }
                                        });
                                    } else {
                                        Toast.makeText(ProfileActivity.this, "Error", Toast.LENGTH_LONG).show();
                                    }
                                    mProfileSendReqBtn.setEnabled(true);
                                }
                            });
                        }


                        if (mCurrent_state.equals("req_sent")) {
                            mProfileSendReqBtn.setEnabled(true);
                            mFriendRequestDatabase.child(mCurrent_user.getUid()).child(user_id).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                    mFriendRequestDatabase.child(user_id).child(mCurrent_user.getUid()).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void aVoid) {
                                            mCurrent_state = "req_sent";
                                            mProfileSendReqBtn.setText("Send Friend Request");
                                            mCurrent_state = "not_friends";
                                            mUserDatabase.keepSynced(true);
                                            mFriendDatabase.keepSynced(true);
                                            mFriendRequestDatabase.keepSynced(true);

                                        }

                                    });

                                }
                            });

                        }


                        if (mCurrent_state.equals("req_received")) {
                            declineRequest.setVisibility(View.INVISIBLE);
                            mProfileSendReqBtn.setEnabled(true);
                            final String currentDate = DateFormat.getDateTimeInstance().format(new Date());
                            mFriendDatabase.child(mCurrent_user.getUid()).child(user_id).setValue(currentDate).addOnSuccessListener(new OnSuccessListener<Void>() {
                                @Override
                                public void onSuccess(Void aVoid) {
                                    mFriendDatabase.child(user_id).child(mCurrent_user.getUid()).setValue(currentDate).addOnSuccessListener(new OnSuccessListener<Void>() {
                                        @Override
                                        public void onSuccess(Void aVoid) {
                                            mFriendRequestDatabase.child(mCurrent_user.getUid()).child(user_id).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                                                @Override
                                                public void onSuccess(Void aVoid) {
                                                    mFriendRequestDatabase.child(user_id).child(mCurrent_user.getUid()).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                                                        @Override
                                                        public void onSuccess(Void aVoid) {
                                                            mCurrent_state = "friends";
                                                            mProfileSendReqBtn.setText("Unfriend User");
                                                            mUserDatabase.keepSynced(true);
                                                            mFriendDatabase.keepSynced(true);
                                                            mFriendRequestDatabase.keepSynced(true);

                                                        }

                                                    });

                                                }
                                            });

                                        }
                                    });
                                }
                            });
                        }


                    }
                }


            });

        declineRequest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                declineRequest.setVisibility(View.INVISIBLE);
                mFriendRequestDatabase.child(mCurrent_user.getUid()).child(user_id).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        mFriendRequestDatabase.child(user_id).child(mCurrent_user.getUid()).removeValue().addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                mCurrent_state= "not_friends";
                                mProfileSendReqBtn.setText("Send Friend Request");
                                mUserDatabase.keepSynced(true);
                                mFriendDatabase.keepSynced(true);
                                mFriendRequestDatabase.keepSynced(true);
                            }

                        });

                    }
                });
            }
        });


    }


}

INDEX.JS FILE

'use strict'

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);


/*
 * 'OnWrite' works as 'addValueEventListener' for android. It will fire the function
 * everytime there is some item added, removed or changed from the provided 'database.ref'
 * 'sendNotification' is the name of the function, which can be changed according to
 * your requirement
 */

exports.sendNotification = functions.database.ref('/notifications/{user_id}/{notification_id}').onWrite((change, context) => {


  /*
   * You can store values as variables from the 'database.ref'
   * Just like here, I've done for 'user_id' and 'notification'
   */

  const user_id = context.params.user_id;
  const notification_id = context.params.notification_id;

  console.log('We have a notification from : ', user_id);

  /*
   * Stops proceeding to the rest of the function if the entry is deleted from database.
   * If you want to work with what should happen when an entry is deleted, you can replace the
   * line from "return console.log.... "
   */

  if(!change.after.val()){

    return console.log('A Notification has been deleted from the database : ', notification_id);

  }

  /*
   * 'fromUser' query retreives the ID of the user who sent the notification
   */

  const fromUser = admin.database().ref(`/notifications/${user_id}/${notification_id}`).once('value');

  return fromUser.then(fromUserResult => {

    const from_user_id = fromUserResult.val().from;

    console.log('You have new notification from  : ', from_user_id);

    /*
     * The we run two queries at a time using Firebase 'Promise'.
     * One to get the name of the user who sent the notification
     * another one to get the devicetoken to the device we want to send notification to
     */

    const userQuery = admin.database().ref(`Users/${from_user_id}/name`).once('value');
    const deviceToken = admin.database().ref(`/Users/${user_id}/device_token`).once('value');

    return Promise.all([userQuery, deviceToken]).then(result => {

      const userName = result[0].val();
      const token_id = result[1].val();

      /*
       * We are creating a 'payload' to create a notification to be sent.
       */

      const payload = {
        notification: {
          title : "New Friend Request",
          body: `${userName} has sent you a request`,
          icon: "default",
          click_action : "com.example.****.chattingapp_TARGET_NOTIFICATION"
        },
        data : {
          from_user_id : from_user_id
        }
      };

      /*
       * Then using admin.messaging() we are sending the payload notification to the token_id of
       * the device we retreived.
       */

      return admin.messaging().sendToDevice(token_id, payload).then(response => {

        return console.log('This was the notification Feature');

      });

    });

  });

});

ERROR I GET

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.example.****.chattingapp, PID: *****
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.****.chattingapp/com.example.****.chattingapp.ProfileActivity}: java.lang.NullPointerException: Can't pass null for argument 'pathString' in child()
                      at com.example.****.chattingapp.ProfileActivity.onCreate(ProfileActivity.java:53)

DATABASE VALUES

在此处输入图片说明

You removed most of the important rows of the Error. However you have to look at it very well and even decode it. It was saying that: there is a problem on "ProfileActivity.onCreate()" method when it calls a "Firebase.....child()" method . There are few rows where you call a "child()" method using a Variable (and not a fixed String), so one of them (please check the Error Log and find the line of that "child()" warning) is the real problem.

So I figured out I needed

 final String user_id;
    String data = getIntent().getStringExtra("user_id");
    if (data == null) {
        user_id = getIntent().getStringExtra("from_user_id");
    } else {
        user_id = getIntent().getStringExtra("user_id");
    }

I wasn't check what string I was getting from my intents, hence the null exceptions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM