그러냐

FCM서버를 이용 Mysql, PHP로 푸시알림 구현하기- Part 2 본문

android

FCM서버를 이용 Mysql, PHP로 푸시알림 구현하기- Part 2

관절분리 2017. 2. 8. 13:41
반응형
앱서버에서 작업하기

Part 1에 이어서 이제 앱서버(웹서버)쪽 작업을 해 보자. 여기서는 PHP를 이용해서 안드로이드 앱(스마트폰이라고 해야 하나)에서 넘어온 토큰 데이터를 서버의 데이터베이스에 저장하는 파일과 데이터베이스에 저장된 토큰정보를 가져와서 FCM에 보내서 푸시알림을 하게 하는 파일을 작성한다. 
마지막으로 워드프레스에서 새로운 글을 등록하면 이 PHP스크립트가 작동하도록 해서 새글 알림을 하도록 할 예정이다. 이게 최종 목적이다. 물론 다른 형태로 얼마든지 활용할 수 있겠지만 ...

mysql 데이터베이스 작업

먼저 phpMyAdmin으로 접속해서 FCM 푸시알림에서 사용할 데이터베이스를 하나 추가하자. fcm이라고 하자.

새로 만들어진 데이터베이스에 새로운 테이블을 추가한다.

CREATE TABLE users( id int(20) NOT NULL AUTO_INCREMENT, Token varchar(200) NOT NULL, PRIMARY KEY(id), UNIQUE KEY(Token) );
php 스트립트 작성

이렇게 토큰을 저장할 테이블을 만들었다. 이제 PHP 스크립트를 작성해 보자.
Part 1에서  register.php라는 토큰을 저장할 스크립트 파일을 지정한 적이 있다. 이제 그 파일을 작성해 주면 되는 것이다.

<?php if(isset($_POST["Token"])){ $token = $_POST["Token"]; //데이터베이스에 접속해서 토큰을 저장 include_once 'config.php'; $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $query = "INSERT INTO users(Token) Values ('$token') ON DUPLICATE KEY UPDATE Token = '$token'; "; mysqli_query($conn, $query); mysqli_close($conn); } ?>

인클루드 한 config.php에는 데이터 베이스 접속 정보와 구글 API_KEY가 등록되어 있다. 이부분은 뭐 코드 작성하기 나름인듯 하다.

<?php define("DB_HOST", "localhost"); define("DB_USER", "DB유저네임"); define("DB_PASSWORD", "DB접속암호"); define("DB_NAME", "fcm"); define("GOOGLE_API_KEY", "구글 API KEY"); ?>

구글 API KEY가 필요하다. 이게 어디 있지?

Firebase 콘솔 페이지에 다시 접속한다.

 

해당 프로젝트의 관리 화면으로 들어가서 클라우드메세징 탭을 선택하면 아래쪽에 서버키가 등록되어 있는 것을 확인할 수 있다. 이 키값을 카피해서 가져 온다.
이 키를 config.php에 입력해 주면 된다.

앱이 폰에 설치되면서(이건 프로래밍 하기 나름이겠지만) 기기를 FCM서버에 등록하고 고유한 토큰을 받는다. 이 토큰을 register.php로 전송해서 데이터베이스에 저장하게 된다. 이게 안되면 뭔가 문제가 있는 것이다.이 단계에서 앱에서 토큰이 제대로 전송이 되는지 체크해야 하고 또 DB에도 제대로 등록이 되는지를 체크해야 한다. 저장된 토큰이 없는데 메세지가 갈리 없다.

<register.php의 실행되 토큰이 DB에 저장된 결과>
FCM 서버에 푸시알림 요청하기

10개의 폰에 앱이 설치 되었다면 토큰 10개가 저장된다. 이제 이 데이터를 가져와서 FCM에 메세지를  보내도록 요청하는 PHP 스크립트를 작성해 보자.

<?php function send_notification ($tokens, $message) { $url = 'https://fcm.googleapis.com/fcm/send'; $fields = array( 'registration_ids' => $tokens, 'data' => $message ); $headers = array( 'Authorization:key =' . GOOGLE_API_KEY, 'Content-Type: application/json' ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields)); $result = curl_exec($ch); if ($result === FALSE) { die('Curl failed: ' . curl_error($ch)); } curl_close($ch); return $result; } //데이터베이스에 접속해서 토큰들을 가져와서 FCM에 발신요청 include_once 'config.php'; $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $sql = "Select Token From users"; $result = mysqli_query($conn,$sql); $tokens = array(); if(mysqli_num_rows($result) > 0 ){ while ($row = mysqli_fetch_assoc($result)) { $tokens[] = $row["Token"]; } } mysqli_close($conn); $myMessage = $_POST['message']; //폼에서 입력한 메세지를 받음 if ($myMessage == ""){ $myMessage = "새글이 등록되었습니다."; } $message = array("message" => $myMessage); $message_status = send_notification($tokens, $message); echo $message_status; ?>

push_notification.php 라는 이름으로 위 코드를 저장했다. 이 스트립트 파일은 데이터베이스에서 현재 저장되어 있는 토큰을 모두 가져와서 FCM 서버에 각각의 폰에 메세지를 보내도록 요청할 것이다.
실제 작동이 되는지 이 PHP파일을 웹브라저에서 불러 실행해 보면 된다. 제대로 작동하지 않는다면 서버에 curl 이 제대로 설치되어 있는지 체크 하자.

 

정상적으로 실행이 되었다면 그 결과를 보여주고 실제 해당 폰에는 푸시알림이 도착해 있을 것이다. 해당 알림을 클릭하면 앱이 실행된다.

여기서 다른 모양으로 폼을 만들어서 관리자가 사용자에게 보낼 메세지를 직접 작성해서 보내는 형식으로 만들어도 되지만 원래의 목적대로 워드프레스에 새글이 등록되면 이 스크립트가 실행되게 해주면 모든 작업이 끝이 난다.

메세지 보내기 입력창을 만들어 보자.

그전에 잠시 메세지를 보낼 수 있는 index 페이지를 간단히 만들어 보자.

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>FCM Push Notification</title> <style type="text/css"> *, *:before, *:after { box-sizing: border-box; } body {background-color: #99cc00;} .messageWrapper {width:500px; margin:0 auto;} ul li {width: 500px; margin:0 auto;} #submitButton { width: 90px; padding:5px; border:2px solid #ccc; -webkit-border-radius: 5px; border-radius: 5px; font: 14px/1.4 "Helvetica Neue", Helvetica, Arial, sans-serif; } </style> </head> <body> <div class="messageWrapper"> <h2>Push Message</h2> <form action="push_notification.php" method="post"> <textarea name="message" rows="4" cols="50" placeholder="메세지를 입력하세요" required></textarea><br> <input type="submit" name="submit" value="Send" id="submitButton"> </form> </div> <?php include("config.php"); $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $sql = "Select Token From users"; $result = mysqli_query($conn,$sql); while ($row = mysqli_fetch_assoc($result)) { ?> <ul> <li><?php echo substr($row["Token"], 0, 30); ?> ...</li> </ul> <?php } ?> </body> </html>

push_notification.php파일도 폼데이터를 넘겨 받을 수 있도록 약간 수정해 줘야 한다.

<알림 도착 확인>
워드프레스 새글 등록되면 푸시알림 보내기

워드프레스에서 아무리 새글을 작성해도 푸시알림이 가지 않더니 겨우 해결 했다. 데이터베이스 연결과정에 문제가 있었다. define으로 변수 지정한것이 말썽이었는데 define이 어떤 개념인지 좀 더 알아 봐야 겠다. 기초가 모르고 할려니 ... ㅋ 암튼 해결!!!

//FCM push notification function push_notification($new_status, $old_status, $post) { if ( $new_status !== 'publish' || $old_status === 'publish' ) return; if ( ! $post_type = get_post_type_object( $post->post_type ) ) return; $myMessage = get_the_title($post); include($_SERVER['DOCUMENT_ROOT'].'/fcm/push_notification.php'); //wp_die("this plugin is a far harder than i imageined"); //return $post; } add_action('transition_post_status', 'push_notification', 10, 3);

워드프레스 테마의 functions.php 파일을 열어서 맨 아래 위 함수를 추가해 준다. 새글이 등록되면 앞 단계에서 만들어 놓은 push_notification.php파일을 인클루드해서 실행되게 했다. 
포스팅한 글을 업데이트 할때나 특정 포스트타입일때만 알림이 가도록 할 수도 있는듯 하다. 하지만 다 필요 없고 새글만 등록되면 가도록 하였다.

<디버깅 1>
혹시 앱에서 정상적으로 토큰이 생성이 되었다고 나오고 이상이 없는데 DB에 아무런 토큰이 저장이 되지 않는다면 아래와 같이 DB접속 관련 파일(register.php)을 수정해서 체크 해보자.

if(isset($_POST["Token"])){ //토큰이 앱에서 제대로 넘어 오는지를 테스트 하기 위해서 //앱에서 토큰이 넘어 오면 하드에 txt파일로 저장하도록 해보자. $myfile = fopen("tokenfile.txt", "w") or die("파일 쓰기를 할 수 없습니다."); $txt = $_POST["Token"]; fwrite($myfile, $txt); fclose($myfile); //파일을 열어서 확인해 봤을때 토큰이 저장되어 있다면 앱에서 토큰을 이 파일로 전송하는데는 문제가 없다는 의미다. //문제는 DB에 넘어 온 토큰을 제대로 저장을 하지 못하는것이다. DB서버를 체크해 봐야 한다. /** $token = $_POST["Token"]; //데이터베이스에 접속해서 토큰을 저장 include_once 'config.php'; $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $query = "INSERT INTO users(Token) Values ('$token') ON DUPLICATE KEY UPDATE Token = '$token'; "; mysqli_query($conn, $query); mysqli_close($conn); **/ }

<디버깅 2>
앱에서 토큰값이 넘어 오기는 하는지를 체크 해 보자. 넘어 온 토큰을 DB에 말고 txt파일로 서버에 저장에 보고 확인하자. 정상적으로 txt파일을 열어서 값이 저장되어 있으면 넘어 오는데는 문제가 없는 것이다. DB 저장에서 문제가 있는 것이다. 다음 단계에서 체크 하자.

<?php $token = "아무런값을 임시로 넣어 놓자. 아니면 앱에서 생성된 토큰을 복사해 넣어된다."; //데이터베이스에 접속해서 토큰저장 include_once 'config.php'; $conn = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); //DB 기본설정에 오류가 있을 경우 if (mysqli_connect_errno()){ echo "Failed to connect to MySQL: " . mysqli_connect_error(); } $query = "INSERT INTO users(Token) Values ('$token') ON DUPLICATE KEY UPDATE Token = '$token'; "; //쓰기과정에 오류가 있을 경우 if(!mysqli_query($conn, $query)){ echo("Error description: " . mysqli_error($conn)); } mysqli_close($conn); ?>

register.php파일의 내용을 위 처럼 해서 웹브라우저에서  직접 실행해 보자. 에러가 있다면 브라우저에 표시해 줄것이다. 암호가 잘못되었다던지 접속에 문제라든지 입력에 문제라든지.... 
여기서 에러가 나온다면 DB에 문제가 있을 수 있으니 유저네임이나 암호, 혹은 기타 DB관련 내용을 점검해 볼 필요가 있겠다.

<디버깅 3>
앞단계에 이상이 없고 push_notification.php를 웹브라저에서 실행했을 때 '페이지를 작동할 수 없다'는 에러가 나온다면 서버에 curl이 설치 되어 있지 않거나 버전이 맞지 않거나 할 수 있는것 같다. 라즈베리파이에 접속해서 php5-curl를 설치해 주자. 이미 curl이 설치 되어 있는것 같은데 뭔가 안 맞는 모양이다. 다시 설치 해 주자.

$ sudo apt-get install php5-curl

그리고 웹서버를 재시작 해준다. 

$ sudo apt-get install php5-curl

다시 push_notification.php를 실행해 보면 제대로 메세지를 보내는 것을 확인 할 수 있다.


출처 : http://cosmosjs.blog.me/220740118136

반응형