質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.13%

iosアプリでFirebaseのpush(FCM)部分でリジェクトされる問題が解決出来ません。

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 3,210

po_tato

score 65

iosアプリにFirebaseのpushサービスを実装しています。

pushは自サーバーにユーザー情報を登録してpush通知を送信するという方法をとっています。
動作は何の問題もなく正常なのですが、これを実装したアプリを審査に提出すると決まって同じ部分でクラッシュしているらしくリジェクトされます。ログを見ると、"tokenRefreshNotification"とあるので、push部分でクラッシュしているんだろうなということは分かるのですが、如何せんこちらでは何の問題もなく、クラッシュを再現することが出来ず一ヶ月くらい途方に暮れています。

何かFCMのpushを実装する上で、抜けている部分(エラー処理など)があるのでしょうか?
私と同じようにFCMを実装している方で問題なく審査に通過している方や、ソースを見て
おかしい部分があると思う方にご意見をいただきたいです。
AppDelegateとクラッシュログを添付しています。
クラッシュログはアプリ名を"MyApp"に変更させて頂いています。

AppDelegate

//  AppDelegate.swift


import UIKit
import Firebase
import UserNotifications
import FirebaseInstanceID
import FirebaseMessaging


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{

    var message0:String?
    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // [START register_for_notifications]
        if #available(iOS 10.0, *) {
            let authOptions : UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {_,_ in })
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            // For iOS 10 data message (sent via FCM)
            FIRMessaging.messaging().remoteMessageDelegate = self
        } else {
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }

        application.registerForRemoteNotifications()
        FIRApp.configure()
        // Add observer for InstanceID token refresh callback.
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.tokenRefreshNotification),
                                               name: .firInstanceIDTokenRefresh,
                                               object: nil)


        return true
    }


    private func application(application: UIApplication, didReceiveRemoteNotification userInfo: [String : AnyObject],
                             fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {


        // Print message ID.
        print("Message ID: )",userInfo["gcm.message_id"]!)

        // Print full message.
        print("%@", userInfo)



        // UIAlertController
        let alertController: UIAlertController = UIAlertController(title: "Alert", message: "Test UIAlertController", preferredStyle: .alert)


        let actionOK = UIAlertAction(title: "OK", style: .default){
            action in
        }
        let actionCancel = UIAlertAction(title: "Cancel", style: .cancel){
            (action) -> Void in
        }

        // actionを追加
        alertController.addAction(actionOK)
        alertController.addAction(actionCancel)

        // UIAlertの起動
        self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
    }
    // [START refresh_token]
    func tokenRefreshNotification(_ notification: Notification) {
        if let refreshedToken = FIRInstanceID.instanceID().token() {
            print("InstanceID token: \(refreshedToken)")
            let ud = UserDefaults.standard
            let id = ud.string(forKey: "id")
            let pass = ud.string(forKey: "pass")
            let param = "id="+id!+"&passwd="+pass!
            /**
             プッシュ登録
             */
            let token = FIRInstanceID.instanceID().token()

            let param_push = param+"&devicetoken="+token!

            let test_push = BG_home(url_dom: "http://test/testApi/test.php", url_param: param_push)
            test_push.get(){json in
                print("test: \(json)")
            }
        }
        // Connect to FCM since connection may have failed when attempted before having a token.
        connectToFcm()


    }
    //FCMサーバーに接続
    func connectToFcm() {
        FIRMessaging.messaging().connect { (error) in
            if (error != nil) {
                print("Unable to connect with FCM. \(error!)")
            } else {
                print("Connected to FCM." ,error as Any)
                UIApplication.shared.applicationIconBadgeNumber = 0

            }
        }
    }


    func applicationWillResignActive(_ application: UIApplication) {

    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        FIRMessaging.messaging().disconnect()
        print("Disconnected from FCM.")
    }

    func applicationWillEnterForeground(_ application: UIApplication) {

    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        connectToFcm()
    }

    func applicationWillTerminate(_ application: UIApplication) {
    }


}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo

        print("%@", userInfo)
        let aps = userInfo["aps"]! as! Dictionary<String,AnyObject>
        let aps2 = aps["alert"]! as! Dictionary<String,AnyObject>
        let push_title = aps2["title"] as! String
        let push_body = aps2["body"] as! String


        // UIAlertController
        let alertController: UIAlertController = UIAlertController(title: push_title, message: push_body, preferredStyle: .alert)

        // 選択肢
        // 異なる方法でactionを設定してみた
        let actionOK = UIAlertAction(title: "OK", style: .default){
            action in
            UIApplication.shared.applicationIconBadgeNumber = 0
        }

        // actionを追加
        alertController.addAction(actionOK)

        // UIAlertの起動
        self.window?.rootViewController?.present(alertController, animated: true, completion: nil)
    }
}
extension AppDelegate : FIRMessagingDelegate {
    // Receive data message on iOS 10 devices.
    func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
        print("%@", remoteMessage.appData)
    }
}


crashlog

{"app_name":"Myapp","timestamp":"2018-04-04 03:10:04.08 +0900","app_version":"1.41","slice_uuid":"d61d1c7e-b94a-3301-8e27-eeef3fcb4db5","adam_id":1168856662,"build_version":"41","bundleID":"com.Myapp","share_with_app_devs":false,"is_first_party":false,"bug_type":"109","os_version":"iPhone OS 11.3 (15E216)","incident_id":"842B54E9-060F-42FF-9638-E0505DE53D5C","name":"Myapp"}
Incident Identifier: 842B54E9-060F-42FF-9638-E0505DE53D5C
CrashReporter Key:   9cab8f54502e04c78114cd75c6340dbd1210669b
Hardware Model:      xxx
Process:             Myapp [268]
Path:                /private/var/containers/Bundle/Application/7FC306BF-F35D-4D41-B865-D129409CC6B1/Myapp.app/Myapp
Identifier:          com.Myapp
Version:             20 (1.41)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.Myapp [433]


Date/Time:           2018-04-04 03:10:03.9596 +0900
Launch Time:         2018-04-04 03:09:56.2755 +0900
OS Version:          iPhone OS 11.3 (15E216)
Baseband Version:    4.56.00
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x0000000104ce9490
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [0]
Triggered by Thread:  0

Filtered syslog:
None found

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   Myapp                        0x0000000104ce9490 specialized AppDelegate.tokenRefreshNotification(_:) + 185488 (AppDelegate.swift:121)
1   Myapp                        0x0000000104ce7120 @objc AppDelegate.tokenRefreshNotification(_:) + 176416 (AppDelegate.swift:0)
2   CoreFoundation                    0x0000000185680c3c 0x1855a9000 + 883772
3   CoreFoundation                    0x00000001856801b8 0x1855a9000 + 881080
4   CoreFoundation                    0x000000018567ff14 0x1855a9000 + 880404
5   CoreFoundation                    0x00000001856fd84c 0x1855a9000 + 1394764
6   CoreFoundation                    0x00000001855b6f38 0x1855a9000 + 57144
7   Foundation                        0x000000018609c8c8 0x186021000 + 506056
8   CoreFoundation                    0x0000000185696910 0x1855a9000 + 973072
9   CoreFoundation                    0x0000000185694238 0x1855a9000 + 963128
10  CoreFoundation                    0x0000000185694768 0x1855a9000 + 964456
11  CoreFoundation                    0x00000001855b4da8 0x1855a9000 + 48552
12  GraphicsServices                  0x0000000187597020 0x18758c000 + 45088
13  UIKit                             0x000000018f59578c 0x18f278000 + 3266444
14  Myapp                        0x0000000104cc7d5c main + 48476 (AppDelegate.swift:14)
15  libdyld.dylib                     0x0000000185045fc0 0x185045000 + 4032

Thread 1:
0   libsystem_kernel.dylib            0x0000000185175d84 0x185153000 + 142724
1   libsystem_pthread.dylib           0x0000000185313eb4 0x185313000 + 3764
2   libsystem_pthread.dylib           0x0000000185313b08 0x185313000 + 2824
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

AppDelegateのtokenRefreshNotificationメソッド内(121行目)で
落ちているようですが、それはどの行ですか?

もし

let param = "id="+id!+"&passwd="+pass!

だったら、idやpassがnilだったということではないでしょうか?

idやpassは、初めてアプリを起動したタイミングでは
まだ保存されていないということはないですか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/04 13:46 編集

    appdelegateのコメントアウトで記載していたのですが、分かりづらかったですね。すみません。おっしゃる通り121行目はその部分を示しています。クラッシュ理由もSIGTRAPですし、nilが入っているのかもしれないなと予想していたのですが、やはりそうでしょうか?一番最初に表示されるviewControllerでidやpassを設定しているのですが、それよりも早くこちらのコードが走ってしまって結果nilになっているということなんでしょうか・・
    let param = "id="+id!+"&passwd"+pass! の上の行に、
    if(id != nil && pass != nil) このif文を追加するのはおかしいでしょうか?

    キャンセル

  • 2018/04/05 00:51 編集

    > if(id != nil && pass != nil) このif文を追加するのはおかしいでしょうか?

    それを入れることで今回のエラーは回避できると思います。
    (問題の処理を単純にif文でスキップして、別のところで問題が出るかどうかは知りません。)

    シミュレータや実機から自分のアプリを一旦削除してから実行したら、
    UserDefaultsから取得したidもpassもnilになり、
    クラッシュが再現できるんじゃないでしょうか?

    キャンセル

  • 2018/04/05 09:48

    それが、何度試しても(TestFlightなどでもやっているんですが)クラッシュしないんですよね。しっかりとアプリは削除してやっているんですが、、、だけど、審査員の方ではそうなっているっぽいですね。とりあえず、上記記載した"if(id != nil && pass != nil)"追加して提出してみたいと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.13%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る