Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.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
在webView中PHP登录后发送Firebase注册令牌_Php_Android_Firebase_Android Webview_Firebase Notifications - Fatal编程技术网

在webView中PHP登录后发送Firebase注册令牌

在webView中PHP登录后发送Firebase注册令牌,php,android,firebase,android-webview,firebase-notifications,Php,Android,Firebase,Android Webview,Firebase Notifications,我真的希望有人能帮我 我在android应用程序中设置了Firebase,该应用程序显示了我使用CakePHP 3构建的网站的网络视图。当我手动将设备令牌添加到数据库中时,Firebase通知确实起作用,但我发现很难理解的是,在登录后如何获取注册令牌,以便我可以将其与用户id合并并将其保存到数据库中 更新 我现在拥有的代码能够将令牌发送到我的PHP服务器。如果我直接将令牌存储到数据库中,它可以正常工作,但是当用户登录时,我需要将令牌与用户id合并,因此我需要将令牌存储在会话中(例如,请参见下面的

我真的希望有人能帮我

我在android应用程序中设置了Firebase,该应用程序显示了我使用CakePHP 3构建的网站的网络视图。当我手动将设备令牌添加到数据库中时,Firebase通知确实起作用,但我发现很难理解的是,在登录后如何获取注册令牌,以便我可以将其与用户id合并并将其保存到数据库中

更新

我现在拥有的代码能够将令牌发送到我的PHP服务器。如果我直接将令牌存储到数据库中,它可以正常工作,但是当用户登录时,我需要将令牌与用户id合并,因此我需要将令牌存储在会话中(例如,请参见下面的PHP代码),但是当我尝试使用
$session->read('device_id')
时,它是空的

我想这可能与我的MainActivity webView在加载onCreate()方法时删除当前PHP会话有关,但我不确定

下面是在PHP中设置会话令牌的代码

StoreTokenToSession(PHP)

MainActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    webView = (WebView) findViewById(R.id.activity_main_webview);

    webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);

    FirebaseMessaging.getInstance().subscribeToTopic("notifications");
    FirebaseInstanceId.getInstance().getToken();

    if (Build.VERSION.SDK_INT >= 19) {
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);

    }
    else if(Build.VERSION.SDK_INT >=11 && Build.VERSION.SDK_INT < 19) {
        webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    }

    CookieManager cookieManager = CookieManager.getInstance(); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
    {
        cookieManager.setAcceptThirdPartyCookies(webView,true);
    }
    else
    {
        cookieManager.setAcceptCookie(true);
    }

    webView.loadUrl("example.com");
}

您需要将用户名存储在服务可以找到它的地方。假设您正在使用身份验证状态侦听器(此代码通常位于您注册用户的活动中的某个位置):

这会将uid存储在共享首选项中,该首选项在应用程序中的任何位置都可用。这意味着在您的服务中,您可以检索uid:

private void sendRegistrationToServer(String token) {
    String uid = PreferenceManager.getDefaultSharedPreferences(this).getString("uid", null);

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
        .url("example.com?device_id="+token+"&uid="+uid)
        .build();

    try {
        Response response = client.newCall(request).execute();
        Log.d(TAG, String.valueOf(response));

    } catch (IOException e) {
        e.printStackTrace();
    }
}
因此,我们读取uid,获取令牌并将它们发送到服务器


这里有一个潜在的竞争条件:如果第一个令牌在用户登录之前进入,
sendRegistrationToServer
还没有uid。我将把这一部分留给读者作为练习,因为它实际上只是为第二个流调用相同的代码。

可能太晚了,无法帮助您完成这一点,也可能不是最好的方法,但我们的解决方案是在调用webview时将令牌作为base64沿着URL传递,然后将其存储在会话中。。。登录后,我们将会话中的令牌保存给登录的用户

大概是这样的:

String kDeviceToken = "https://hostname.com?deviceToken=%s";
String token = SessionManager.getInstance(getApplicationContext()).getFirebaseToken();
byte[] data = token.getBytes("UTF-8");
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
String url = String.format(kDeviceToken, base64);
webView.loadUrl(url);

我知道可能已经很晚了,但我一直在寻找这个问题,最终我找到了一个可能有用的解决方案


您可以在请求的url中以post的形式发送令牌,然后在php中捕获此post参数并将其放入会话,这样当您成功登录时,您可以使用用户id将此会话值发送到数据库,这也将使您能够使令牌与活动帐户连接,这意味着如果用户注销并使用新帐户登录,令牌将连接到新用户id,但您必须确保发送的令牌未与其他用户连接,如果已连接,则必须将此用户id更改为新的用户id

您似乎在这里进行了各种尝试。我会放弃使用webview的努力,它看起来比它的价值更痛苦。但是
sendRegistrationToServer()
中的一个被注释掉了。如果启用该代码(并删除webview内容),会发生什么?谢谢您的回复。我知道firebase getToken()是异步调用的,因此我必须等待令牌加载。现在的问题是,我将如何加载应用程序,然后等待令牌通过,一旦令牌存在,将其发送到PHP,最后向用户显示登录部分。我正在考虑一个splashscreen,但不知道如何实现它,因为我是android新手,
onTokenRefresh()
将在刷新令牌时被调用,所以您不必等待它。不过,您可能需要等待
OkHttpClient
请求,因为这也是一个异步调用。但是我没有使用过OkHttp,一般来说,我认为在这个简单的代码中没有太多需要等待的地方。谢谢您的回复。有时,当我第一次加载我的应用程序时,令牌为空,这一定与令牌不可用有关。我如何实现类似于
splashscreen->if(noToken){继续使用splashscreen直到令牌,然后删除主要活动的splashscreen}
任何帮助都将不胜感激。。这是应用程序流程,我不是很流利。很抱歉这段代码很完美,但是登录和注册都是通过webView通过CakePHP完成的,所以我无法获取用户名。我是遗漏了一些简单的东西还是很复杂?在过去的4天里,我一直在研究这个问题,所以我不能告诉你答案的更多细节,它可以帮助任何从谷歌找到他们的方式的用户。我的一个未被接受的答案仍然偶尔会让我在投票中获得代表性的支持。@Matheusdardene什么是SessionManager?我是否需要将Firebase的文件导入mainactivity.java?
FirebaseAuth
    .getInstance()
    .addAuthStateListener(new FirebaseAuth.AuthStateListener() {
        public void onAuthStateChanged(FirebaseAuth firebaseAuth) {
            setCurrentUser(firebaseAuth.getCurrentUser().getUid());
            PreferenceManager
            .getDefaultSharedPreferences(this)
            .edit()
            .putString("uid", mUsername)
            .commit();
        }
    });
private void sendRegistrationToServer(String token) {
    String uid = PreferenceManager.getDefaultSharedPreferences(this).getString("uid", null);

    OkHttpClient client = new OkHttpClient();

    Request request = new Request.Builder()
        .url("example.com?device_id="+token+"&uid="+uid)
        .build();

    try {
        Response response = client.newCall(request).execute();
        Log.d(TAG, String.valueOf(response));

    } catch (IOException e) {
        e.printStackTrace();
    }
}
String kDeviceToken = "https://hostname.com?deviceToken=%s";
String token = SessionManager.getInstance(getApplicationContext()).getFirebaseToken();
byte[] data = token.getBytes("UTF-8");
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
String url = String.format(kDeviceToken, base64);
webView.loadUrl(url);