Error Code: 401 () when sending FCM notification using a server

0

I'm having trouble sending notification using Firebase Cloud Messaging on Android. I'm using the method below:

public void enviaNotificacao(String mensagem, Pedido pedido, String token) {
    Sender sender = new Sender(apiKey);
    Message message = new Message.Builder()
            .addData("message", mensagem)
            .addData("pedido", getGson().toJson(pedido, Pedido.class))
            .build();
    try {
        Result result = sender.send(message, token, 3);

        System.out.println(result.getCanonicalRegistrationId());
        System.out.println(result.getErrorCodeName());
        System.out.println(result.getMessageId());
        System.out.println(pedido.getTokenGCM().substring(0, 10));

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

The following error appears:

com.google.android.gcm.server.InvalidRequestException: HTTP Status Code: 401()
at com.google.android.gcm.server.Sender.makeGcmHttpRequest(Sender.java:484)
at com.google.android.gcm.server.Sender.sendNoRetry(Sender.java:215)
at com.google.android.gcm.server.Sender.send(Sender.java:182)
at com.t2ti.cardapio.Cardapio.enviaNotificacao(Cardapio.java:335)
at com.t2ti.cardapio.Cardapio.geraPedido(Cardapio.java:319)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:212)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:121)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:181)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:146)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1527)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1484)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

I'm using the Web API Key provided in firebase settings

    
asked by anonymous 06.09.2018 / 15:07

3 answers

0

SOURCE: Translated from link

You should take a look at the GCM documents where you explain GCM's response: link and troubleshooting 401 error code: link

Description of the documents:

 Erro de autenticação: A conta do remetente que você está tentando usar para enviar uma mensagem não pôde ser autenticada. Causas possíveis são:

 Cabeçalho de autorização ausente ou com sintaxe inválida.

 Número de projeto inválido enviado como chave.

 Chave válida, mas com o serviço GCM desativado.

 Solicitação originada de um servidor não listado na lista de permissões dos IPs da chave do servidor.

So I'd check to see if you're setting the authorization header correctly and if the Google Project number is properly configured with GCM and accepting the IP of the servers.

    
08.09.2018 / 04:19
0

You did right following the link How to find Sender ID

I was putting the wrong token, but now I have another problem, the message content does not appear, here is an example below of how I am using the notification method:

enviaNotificacao("Pedido recebido em nosso banco de dados", pedido, pedido.getTokenGCM());

An empty notification appears.

    
10.09.2018 / 18:24
0

Blank Notification case has been resolved modified RegistrationIntentService

package com.t2ti.cardapiobalcao;

import android.app.IntentService;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
import com.t2ti.cardapio.Constantes;
import com.t2ti.cardapio.model.DetalheDenuncia;

import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import java.io.File;
import java.io.IOException;

public class RegistrationIntentService extends IntentService {

    private static final String TAG = "RegIntentService";
    private static final String[] TOPICS = {"global"};

    public RegistrationIntentService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);

        try {
            // [START register_for_gcm]
            // Initially this call goes out to the network to retrieve the token, subsequent calls
            // are local.
            // [START get_token]

            String token = FirebaseInstanceId.getInstance().getToken();
            // TODO: Implement this method to send any registration to your app's servers.
            sendRegistrationToServer(token);

            // Subscribe to topic channels
            subscribeTopics(token);

            // You should store a boolean that indicates whether the generated token has been
            // sent to your server. If the boolean is false, send the token to your server,
            // otherwise your server should have already received the token.
            sharedPreferences.edit().putBoolean(Constantes.SENT_TOKEN_TO_SERVER, true).apply();
            // [END register_for_gcm]
        } catch (Exception e) {
            Log.d(TAG, "Failed to complete token refresh", e);
            // If an exception happens while fetching the new token or updating our registration data
            // on a third-party server, this ensures that we'll attempt the update at a later time.
            sharedPreferences.edit().putBoolean(Constantes.SENT_TOKEN_TO_SERVER, false).apply();
        }
        // Notify UI that registration has completed, so the progress indicator can be hidden.
        Intent registrationComplete = new Intent(Constantes.REGISTRATION_COMPLETE);
        LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
    }

    /**
     * Persist registration to third-party servers.
     *
     * Modify this method to associate the user's GCM registration token with any server-side account
     * maintained by your application.
     *
     * @param token The new token.
     */
    public void sendRegistrationToServer(String token) {
        try {
            File arquivoXml = new File(getFilesDir(), "denuncia.xml");
            Serializer serializer = new Persister();
            DetalheDenuncia denuncia = new DetalheDenuncia();
            if (arquivoXml.exists()) {
                denuncia = serializer.read(DetalheDenuncia.class, arquivoXml);
            }

            denuncia.setTokenGCM(token);

            serializer.write(denuncia, arquivoXml);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
     *
     * @param token GCM token
     * @throws IOException if unable to reach the GCM PubSub service
     */
    // [START subscribe_topics]
    private void subscribeTopics(String token) throws IOException {
        FirebaseMessaging.getInstance().subscribeToTopic("mytopic");
    }
    // [END subscribe_topics]

}
    
20.09.2018 / 02:20