web-dev-qa-db-ja.com

Spring Bootを使用して通知(FCM)を送信する方法

APIを持っていて、Meetingというテーブルの何かを変更したときにスマートフォンに通知を送信したいと思います。そのために、タイプPOSTのメソッドを作成しています。ここで、次のJSON BodyとAuthorizationキー( firebaseによって提供されます)および次のURLhttps://fcm.googleapis.com/fcm/send

@Headers -> *******



 {
       "to": "/topics/groupNameChoosenByYou",
       "data": {
          "title": "Your title",
          "message": "Your message"
       }
    }

これは私のAndroidPushNotificationsServiceです

@Service
public class AndroidPushNotificationsService {

    private static final String FIREBASE_SERVER_KEY = "AAAAq88vWWE:APA91bF5rSyqGbx26AY5jm6NsEfwJynQsnTd1MPFOTOz1ekTGZyof3Vz6gBb0769MLLxD7EXMcqKiPIHnqLh5buHEeUASnpsn-ltxR1J8z3kWJIAPNWlPZB0r0zKkXMyWkrbT3BLPWmCdi-NZnP3Jkb2z-QqtwJt5Q";
    private static final String FIREBASE_API_URL = "https://fcm.googleapis.com/fcm/send";

    @Async
    public CompletableFuture<String> send(HttpEntity<String> entity) {

        RestTemplate restTemplate = new RestTemplate();

        ArrayList<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new HeaderRequestInterceptor("Authorization", "key=" + FIREBASE_SERVER_KEY));
        interceptors.add(new HeaderRequestInterceptor("Content-Type", "application/json"));
        restTemplate.setInterceptors(interceptors);

        String firebaseResponse = restTemplate.postForObject(FIREBASE_API_URL, entity, String.class);

        return CompletableFuture.completedFuture(firebaseResponse);
    }
}

これは私のHeaderRequestInterceptorです

public class HeaderRequestInterceptor implements ClientHttpRequestInterceptor {

    private final String headerName;
    private final String headerValue;

    public HeaderRequestInterceptor(String headerName, String headerValue) {
        this.headerName = headerName;
        this.headerValue = headerValue;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
        HttpRequest wrapper = new HttpRequestWrapper(request);
        wrapper.getHeaders().set(headerName, headerValue);
        return execution.execute(wrapper, body);
    }
}

これは私のコントローラーです

@RestController
public class WebController {

    private final String TOPIC = "test";

    @Autowired
    AndroidPushNotificationsService androidPushNotificationsService;

    @RequestMapping(value = "/send", method = RequestMethod.GET, produces = "application/json")
    public ResponseEntity<String> send() throws JSONException {

        JSONObject body = new JSONObject();
        body.put("to", "/topics/" + TOPIC);
        body.put("priority", "high");

        JSONObject notification = new JSONObject();
        notification.put("title", "JSA Notification");
        notification.put("body", "Happy Message!");

        JSONObject data = new JSONObject();
        data.put("Key-1", "JSA Data 1");
        data.put("Key-2", "JSA Data 2");

        body.put("notification", notification);
        body.put("data", data);

        HttpEntity<String> request = new HttpEntity<>(body.toString());

        CompletableFuture<String> pushNotification = androidPushNotificationsService.send(request);
        CompletableFuture.allOf(pushNotification).join();

        try {
            String firebaseResponse = pushNotification.get();

            return new ResponseEntity<>(firebaseResponse, HttpStatus.OK);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return new ResponseEntity<>("Push Notification ERROR!", HttpStatus.BAD_REQUEST);
    }
}

問題は、http://localhost:8080/springbootapi/sendに移動すると404が表示されますが、サーバーは実行されていることです。 FCMAPIにはPOSTメソッドが必要であり、/ sendメソッドではGETを実行しているため、基本的にAPIを作成しているため、使用しているコードですべてが問題ないかどうかを知りたいと思いました。テーブルが変更されたときにユーザーに通知を提供するために他のAPIを呼び出すことが主な目的です。これを行うためのより良い方法はありますか?

3
José Nobre

_@RestController_アノテーションの下に、@RequestMapping("/springbootapi")または任意のパスを追加します。

1
Iulian

FCMにはPOSTが必要であり、restTemplateでPOSTを送信しています。コントローラがGETであるかDELETEであるかは関係ありません。ただし、取得するのではなく送信するため、POSTにする必要があります。 404は、間違ったURLを入力していることを意味します。 http:// localhost:8080/send (8080ポートを使用している場合)

1
Moler

スプリングブートアプリケーションへのコンテキストパスを設定していないことを確認してください(Check log and search for Context path which might defined in Application.yml/properties)

404を取得している場合、ポート8080は完全に問題ありませんが、Springブートアプリケーションによってのみポートが開かれていることを確認してください(check the spring boot printed logs in console for port also)

私があなたの質問から信じているのは、404エラーはFCMが原因ではなく、マシンで実行しているアプリケーションが原因であるということです。

0
Ravi