首页 > 解决方案 > 在我的 Grocery 应用程序中遇到 firebase 推送通知

问题描述

我正在为我的 fyp 创建一个 android 应用程序,我已经完成了所有代码,但卡住了 firebase 推送通知。这个应用程序有两个不同的用户,一个是客户,另一个是店主。我试图在我的店主应用程序中实现推送通知。在店主应用程序中,当他接受客户订单时,我想在客户应用程序中发送通知,我尝试使用此代码但无法发送通知。我正在为此应用程序使用 firebase 实时数据库。

我已经尝试过去 3 天来解决这个问题,但无法解决这个问题。我也在 youtube 和 stackover flow 上搜索,但找不到任何令人满意的解决方案。

提到了我为实现 firebase 推送通知而编写的代码。

片段顺序

public class fragmentOrders extends Fragment {

    private View orderView;
    private CompositeDisposable compositeDisposable = new CompositeDisposable();
    private IFCMService ifcmService;
    private DatabaseReference tokenRef;
    public fragmentOrders() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
         orderView = inflater.inflate(R.layout.fragment_orders, container, false);

        ifcmService = RetrofitFCMClient.getInstance().create(IFCMService.class);

        tokenRef = FirebaseDatabase.getInstance().getReference(common.TOKEN_REF);


        return orderView;
    }


    @Override
    public void onStop() {
        super.onStop();
        compositeDisposable.clear();
    }

    private void showOrders() {

        FirebaseRecyclerOptions<OrderModel> options = new FirebaseRecyclerOptions.Builder<OrderModel>()
                .setQuery(orderRef,OrderModel.class)
                .build();

        FirebaseRecyclerAdapter<OrderModel,OrderViewHolder> adapter = new FirebaseRecyclerAdapter<OrderModel, OrderViewHolder>(options) {
            @Override
            protected void onBindViewHolder(@NonNull OrderViewHolder holder, int position, @NonNull OrderModel model) {
                holder.CustomerName.setText(model.getName());
                holder.CustomerNumber.setText(model.getNodePhone());
                holder.ShippingAddress.setText(model.getAddress());
                holder.OrderDateTime.setText(model.getDate() + " , " + model.getTime());
                holder.TotalPrice.setText(model.getTotalprice());


                holder.btnConfirmOrder.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        holder.cancelLayout.setVisibility(View.GONE);
                        holder.btnConfirmOrder.setText(model.getUid());
                                                confirmOrder(model);
                    }
                });

            }

            @NonNull
            @Override
            public OrderViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(getContext()).inflate(R.layout.view_order_items,parent,false);
                return new OrderViewHolder(view);
            }
        };
        orderList.setAdapter(adapter);
        adapter.startListening();
    }


            }
        });
    }

    private void confirmOrder(OrderModel model) {
     tokenRef.child(model.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()){
                    TokenModel tokenModel = dataSnapshot.getValue(TokenModel.class);
                    Map<String,String> notiData = new HashMap<>();
                    notiData.put(common.NOTI_TITLE,"Order Confirmed");
                    notiData.put(common.NOTI_CONTENT,"Your Shopping Order is Confirmed and Shipped");
                    //ShowNotification(tokenModel,notiData);
                    FCMSendData sendData = new FCMSendData(tokenModel.getToken(),notiData);
                    compositeDisposable.add(ifcmService.sendNotification(sendData)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new Consumer<FCMResponse>() {
                                @Override
                                public void accept(FCMResponse fcmResponse) throws Exception {

                                    if (fcmResponse.getSuccess() == 1){
                                        Toast.makeText(getContext(), "Order confirmed success", Toast.LENGTH_SHORT).show();
                                    }else {
                                        Toast.makeText(getContext(), "Order confirmed success but faild to send notification", Toast.LENGTH_SHORT).show();
                                    }
                                }
                            }, new Consumer<Throwable>() {
                                @Override
                                public void accept(Throwable throwable) throws Exception {
                                    Toast.makeText(getContext(), throwable.getMessage(), Toast.LENGTH_SHORT).show();
                                }
                            })
                    );

                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Toast.makeText(getContext(), databaseError.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });


    }

    public class OrderViewHolder extends RecyclerView.ViewHolder{

        TextView CustomerName,CustomerNumber,ShippingAddress,OrderDateTime,TotalPrice;
        Button btnViewOrderProducts,btnConfirmOrder,btnCancelOrder,btnCallCustomer;
        RelativeLayout cancelLayout;
        public OrderViewHolder(@NonNull View itemView) {
            super(itemView);
            CustomerName = itemView.findViewById(R.id.customer_name);
            CustomerNumber = itemView.findViewById(R.id.customer_phone);
            ShippingAddress = itemView.findViewById(R.id.customer_shipping_address);
            OrderDateTime = itemView.findViewById(R.id.order_date_time);
            btnViewOrderProducts = itemView.findViewById(R.id.btn_view_order_product);
            TotalPrice = itemView.findViewById(R.id.order_total_price);
            btnConfirmOrder = itemView.findViewById(R.id.btn_confirm_order);
            btnCancelOrder = itemView.findViewById(R.id.btn_cancel_order);
            btnCallCustomer = itemView.findViewById(R.id.btn_call_customer);
            cancelLayout = itemView.findViewById(R.id.canel_layout);
        }
    }
}

常见的

public class common {
    public static final String NOTI_TITLE = "title";
    public static final String NOTI_CONTENT = "content";
    public static final String TOKEN_REF = "Tokens";



    public static void showNotification(Context context, int id, String title, String content, Intent intent) {
        PendingIntent pendingIntent = null;
        if (intent !=null){
            pendingIntent = PendingIntent.getActivity(context,id,intent,PendingIntent.FLAG_UPDATE_CURRENT);
            String NOTIFICATION_CHANNEL_ID = "Designer_Club_App";
            NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID
                 , "Designer Club", NotificationManager.IMPORTANCE_DEFAULT);

                notificationChannel.setDescription("Designer Club");
                notificationChannel.enableLights(true);
                notificationChannel.setVibrationPattern(new long[]{0,1000,500,1000});
                notificationChannel.enableVibration(true);
                notificationChannel.setLightColor(android.R.color.white);

                notificationManager.createNotificationChannel(notificationChannel);
            }

            NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
                    .setSmallIcon(R.drawable.notification_icon)
                    .setContentTitle(title)
                    .setContentText(content)
                    .setAutoCancel(true)
                    .setPriority(NotificationCompat.PRIORITY_DEFAULT);

            if (pendingIntent != null){
                builder.setContentIntent(pendingIntent);
                Notification notification = builder.build();
                notificationManager.notify(id,notification);
            }
        }
    }


}

FCM响应

import java.util.List;

public class FCMResponse {
    private long multicast_id;
    private int success,failure,canonical_ids;
    private List<FCMResult> results;
    private long message_id;

    public FCMResponse() {
    }

    public long getMulticast_id() {
        return multicast_id;
    }

    public void setMulticast_id(long multicast_id) {
        this.multicast_id = multicast_id;
    }

    public int getSuccess() {
        return success;
    }

    public void setSuccess(int success) {
        this.success = success;
    }

    public int getFailure() {
        return failure;
    }

    public void setFailure(int failure) {
        this.failure = failure;
    }

    public int getCanonical_ids() {
        return canonical_ids;
    }

    public void setCanonical_ids(int canonical_ids) {
        this.canonical_ids = canonical_ids;
    }

    public List<FCMResult> getResults() {
        return results;
    }

    public void setResults(List<FCMResult> results) {
        this.results = results;
    }

    public long getMessage_id() {
        return message_id;
    }

    public void setMessage_id(long message_id) {
        this.message_id = message_id;
    }
}

FCM结果

public class FCMResult {
    private String message_id;

    public FCMResult() {
    }

    public String getMessage_id() {
        return message_id;
    }

    public void setMessage_id(String message_id) {
        this.message_id = message_id;
    }
}

FCMSendData

import java.util.Map;

public class FCMSendData {

    private String to;
    private Map<String,String> data;

    public FCMSendData(String to, Map<String, String> data) {
        this.to = to;
        this.data = data;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public Map<String, String> getData() {
        return data;
    }

    public void setData(Map<String, String> data) {
        this.data = data;
    }
}

IFCM服务

import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.Headers;
import retrofit2.http.POST;

public interface IFCMService {

    @Headers({
            "Content-Type:application/json",
            "Authorization:key=AAAAzkiH50E:APA91bETfnykxzAHx7Q4g5EFcPqZRHuyWi8S72OlnzFvxY4x_9o5MWl-BuxSB2ZUYt73Im1RJsOb55d7cTe3IPZR4fLIAaoJd_CaH1THCq3lxV4Rs6DfDdTtrC2HgIKNEgON2rD2ICGb"
    })
    @POST("fcm/send")
    Observable<FCMResponse> sendNotification(@Body FCMSendData body);

}

改造FCMClient

import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitFCMClient {
    private static Retrofit instance;
    public static Retrofit getInstance(){

        if (instance == null)
            instance = new Retrofit.Builder()
                    .baseUrl("https://fcm.googleapis.com/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();

            return instance;
    }
}

我的 FCM 服务

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFCMService extends FirebaseMessagingService {


    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {

        Map<String,String> dataRecv = remoteMessage.getData();

         if (dataRecv != null){
             common.showNotification(this,new Random().nextInt(),
                     dataRecv.get(common.NOTI_TITLE),
                     dataRecv.get(common.NOTI_CONTENT),
                     null);
         }

    }

    @Override
    public void onNewToken(String s) {
        super.onNewToken(s);
        common.updateToken(this,s);
    }
}

依赖关系

  implementation 'com.google.firebase:firebase-auth:19.3.0'
    implementation 'com.google.firebase:firebase-database:19.2.1'
    implementation 'com.google.firebase:firebase-messaging:20.1.4'
    implementation 'com.google.firebase:firebase-storage:19.1.1'
    implementation 'com.firebaseui:firebase-ui-database:5.0.0'

    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.6.1'

    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation 'io.reactivex.rxjava2:rxjava:2.2.9'

显现

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.designerclubadmin">

    <application
        <service android:name=".services.MyFCMService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>
    </application>

</manifest>

标签: android

解决方案


你应该在 serverAPP 中的 mainActivity 中更新令牌,就像客户端应用程序一样,在这样的两个应用程序中相同

     private void GotoHomeActivity(ServerUserModel serverUserModel) {
              FirebaseInstanceId.getInstance()
                        .getInstanceId()
                        .addOnFailureListener(new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                Toast.makeText(MainActivity.this, ""+e.getMessage(), Toast.LENGTH_SHORT).show();
                                dialog.dismiss();
                                common.currentServerUser = serverUserModel;
                                startActivity(new Intent(MainActivity.this , HomeActivity.class));
                                finish();
                            }
                        }).addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
                    @Override
                    public void onComplete(@NonNull Task<InstanceIdResult> task) {
                        dialog.dismiss();
                        common.currentServerUser = serverUserModel;
                        //this what i talk about (Update Token)
                        common.UpdateToken(MainActivity.this, task.getResult().getToken());
                        startActivity(new Intent(MainActivity.this , HomeActivity.class));
                        finish();
                    }
                });
}

通用类中的 UpdateToken

  public static void UpdateToken(Context context, String newToken) {

    FirebaseDatabase.getInstance()
            .getReference(common.TOKEN_REF)
            .child(common.currentServerUser.getUid())
            .setValue(new TokenModel(common.currentServerUser.getPhone() , newToken))
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {

                    Toast.makeText(context, ""+e.getMessage(), Toast.LENGTH_SHORT).show();

                }
            });

}

推荐阅读