Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何处理FirebaseInstanceId.getInstance().getToken()=null_Android_Firebase_Firebase Cloud Messaging - Fatal编程技术网

Android 如何处理FirebaseInstanceId.getInstance().getToken()=null

Android 如何处理FirebaseInstanceId.getInstance().getToken()=null,android,firebase,firebase-cloud-messaging,Android,Firebase,Firebase Cloud Messaging,我刚迁移到FCM。我已经添加了从FireBaseInstancedService扩展而来的类,以便在适当的时候接收refreshedToken 我的问题是针对用户第一次安装我的应用程序时,由于某种原因,无法从onTokenRefresh接收注册Id的情况。我们该怎么处理?我可以从我的FireBaseInstancedService类中设置一个广播接收器,当收到注册Id时,该接收器将通知主要活动吗?据我所知,只有当您尝试在模拟器上运行您的应用程序时(google play服务不在模拟器上)以及当您

我刚迁移到FCM。我已经添加了从FireBaseInstancedService扩展而来的类,以便在适当的时候接收refreshedToken


我的问题是针对用户第一次安装我的应用程序时,由于某种原因,无法从onTokenRefresh接收注册Id的情况。我们该怎么处理?我可以从我的FireBaseInstancedService类中设置一个广播接收器,当收到注册Id时,该接收器将通知主要活动吗?

据我所知,只有当您尝试在模拟器上运行您的应用程序时(google play服务不在模拟器上)以及当您在google play商店上使用双电子邮件Id时,令牌才会为空(在您的实际设备上),但仅验证了一个电子邮件id的使用情况。这些情况将为您提供空令牌,并且我已经在我的新项目中实现了FCM。因此,在其他情况下,令牌不会为空。

根据您的应用程序逻辑,您可以编写代码来处理“新”直接在
FirebaseInstanceIdService.onTokenRefresh()
方法中使用令牌,或者如果发生此事件时需要更改UI,可以使用本地广播将此信息发送到活动

请注意,当调用
onTokenRefresh()
时,您的活动可能会关闭

一个可能的实施方案可以是两个选项的混合:

  • onTokenRefresh()
    中添加一些逻辑以将令牌发送到服务器
  • 如果您有一个UI需要在令牌可用时更改,请使用LocalBroadcastReceiver通知您的活动
    • 如果您的设备没有连接到internet,则不会调用onTokenRefresh(),您应通知用户其设备没有internet连接
    • firebase有自己的网络更改侦听器,当设备连接到internet时,然后尝试获取令牌并将其返回,此时您可以通过发送本地广播接收器告知您的主要活动已收到注册令牌
    使用以下代码:

        @Override
    public void onTokenRefresh() {
    
        // Get updated InstanceID token.
        String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    
        Log.d("FCN TOKEN GET", "Refreshed token: " + refreshedToken);
    
        final Intent intent = new Intent("tokenReceiver");
        // You can also include some extra data.
        final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(this);
        intent.putExtra("token",refreshedToken);
        broadcastManager.sendBroadcast(intent);
    
    
    }
    
    在您的主要活动中:

        public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
       LocalBroadcastManager.getInstance(this).registerReceiver(tokenReceiver,
                new IntentFilter("tokenReceiver"));
    
    }
    
    BroadcastReceiver tokenReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String token = intent.getStringExtra("token");
            if(token != null)
            {
                //send token to your server or what you want to do
            }
    
        }
    };
    
    }
    

    使用该类扩展为

    public class MyFirebaseInstanceIDService  extends FirebaseInstanceIdService {
    
        private static final String TAG = "MyFirebaseIIDService";
        public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
    
    
        @Override
        public void onTokenRefresh() {
            String refreshedToken = FirebaseInstanceId.getInstance().getToken();
            Log.d(TAG, "Refreshed token: " + refreshedToken);
    
            Toast.makeText(MyFirebaseInstanceIDService.this,refreshedToken,Toast.LENGTH_LONG).show();
        }
    }
    

    我也面临着同样的问题。我浏览了很多SO帖子和其他论坛,找到了一个适合我的解决方案。FCM文档说使用这种方法来获取令牌

    String refreshedToken = FirebaseInstanceId.getInstance().getToken();
    
    我在网上找到一篇帖子(很抱歉,我不记得是哪一篇了。我刚才找到的),它使用了这种方法:

    String refreshedToken = FirebaseInstanceId.getInstance().getToken() (String authorizedEntity, String scope);
    
    FCM文档将第一种方法描述为:

    返回默认Firebase项目的主令牌

    而第二个描述为:

    返回一个令牌,该令牌授权实体代表实例ID标识的应用程序执行操作。 这类似于OAuth2令牌,只是它应用于应用程序实例而不是用户。 例如,要获取可用于通过FirebaseMessaging向应用程序发送消息的令牌,请设置为发件人ID,然后设置为“FCM”


    我一直在研究为什么第一个方法调用要花费更长的时间才能返回令牌,但我还没有找到答案。希望这能有所帮助。

    在manifest.xml文件中更改这一点 工具:node=“替换” 到
    工具:node=“merge”。

    如果您在模拟器上运行它,请检查您是否在工具->Android->SDK管理器->SDK工具->Google play服务中启用了Google play服务

    安装后,重新启动Android Studio和模拟器


    它对我很有效

    我想,
    FirebaseInstanceId.getInstance().getToken()
    仅在Internet不可用时才会返回null。是的,那么如何处理这个问题呢?所以,只需设置
    LocalBroadcastReceiver
    。从您的方法发送广播
    onTokenRefresh()
    和inside
    MainActivity
    通过设置BroadcastReceiver捕捉广播。谢谢@ChintanSoni。我会试试这个!看起来FCM在像小米这样有Chinise OS版本的设备上没有完全功能(它没有GooglePlay服务,但即使安装了GPServices,它仍然没有完全功能)在应用程序能够获取有效令牌之前,令牌将为空。获取令牌的要求是:1.设备上安装了google play服务,2.设备连接到internet。即使满足要求,令牌也可能需要一些时间(通常<10秒)可用。这取决于本地条件,如网络、设备负载等。如果存在延迟,将调用自动
    onTokenRefresh
    方法并获取更新的令牌,如果不存在internet,则首先在应用程序中处理
    internet连接性
    ,我想知道您是否可以解释如果没有代币。在我的应用程序中,从一开始就必须有一个代币。我想它应该是这样的,
    splashscreen->if(noToken){继续使用splashscreen直到代币,然后删除主要活动的splashscreen}
    当您的应用程序启动FirebaseInstanceId服务尝试从FCM获取令牌时,您可以在启动屏幕中显示进度条,直到FirebaseInstanceId服务返回令牌。如果FirebaseInstanceId返回令牌,则将其发送到您的应用程序服务器,并告知您的启动屏幕已收到带有L的活动令牌ocalBroadcastManager然后关闭启动屏幕并显示你的应用程序主活动,否则告诉启动屏幕活动令牌无法接收并向用户显示消息用户连接到internet后你没有internet连接FirebaseInstanceId服务尝试重新获取令牌谢谢你的响应,我将尝试实现。另一个如果你能帮助我理解的话,我的Android应用程序是用PHP开发的,并显示为webView。我可以将令牌发送到服务器,但我如何将令牌存储在PHP服务器上,以便在用户注册时使用,以便我可以将令牌和用户_存储在数据库中