使用android studio和firebase时,单击通知时,我的应用程序(在后台或前台)在API 26设备上崩溃。而当我使用API 23设备时,关闭应用程序并单击通知后,应用程序将崩溃,但当应用程序处于后台/前景时仍可以处理通知。我不明白问题所在,不胜感激。
通知服务
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);
}
}
}
用户活动
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);
}
});
}
});
}
});
}
}
配置文件活动
'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');
});
});
});
});
INDEX.JS文件
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)
我遇到错误
{{1}}
数据库值
答案 0 :(得分:0)
您删除了错误的大部分重要行。 但是,您必须非常仔细地看待它,甚至对其进行解码。有人说:“ ProfileActivity.onCreate()”方法调用“ Firebase ..... child()”方法时出现问题。使用变量(而不是固定的字符串)调用“ child()”方法的行很少,因此其中一行(请检查错误日志并找到“ child()”警告的行)是真正的问题。
答案 1 :(得分:0)
所以我发现我需要
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");
}
我没有检查从意图中得到的字符串,因此没有null异常。