【问题标题】:cordova-plugin-facebook4 post with image error on Androidcordova-plugin-facebook4 在 Android 上发布带有图像错误的帖子
【发布时间】:2017-02-02 09:29:53
【问题描述】:

我正在为 iOS 和 Android 开发一个具有 angular 和 ionic 的混合应用程序,在将图像发布到 Facebook 时遇到错误。仅当我在 Android 设备上运行该应用程序时才会出现该错误。我正在使用cordova-plugin-facebook4,并且像获取朋友和登录这样的查询工作正常。

特定部分的代码:

function makeCallToFacebookWithImage(url){
    console.log("share that to facebook with image");
    var facebookString = "/me/photos?method=post&url="+encodeURI(url)+"&caption="+$scope.comment;
    console.log("facebookString with image: "+facebookString);
    facebookConnectPlugin.getLoginStatus(function(loginStatus){
        // if already loggedIn
        if(loginStatus.status == "connected"){
            facebookConnectPlugin.api(facebookString, ["publish_actions"], function(response){
                // success
                console.log("success "+JSON.stringify(response));
            }, function(response){
                // error
                console.log("error "+JSON.stringify(response));
            });
        }
    }, function(error){
        console.log(error);
    })
}

第4行的console.log:

带有图片的facebookString:/me/photos?method=post&url=https://firebasestorage.googleapis.com/URL?alt=media&token=4420080a-41d8-4816-bf62-5bfb159d1da5&caption=FBTest

错误信息:

error {"errorCode":"100","errorType":"OAuthException","errorMessage":"Invalid parameter","errorUserMessage":"您的照片无法上传。照片应小于 4 MB并保存为 JPG、PNG、GIF 或 TIFF 文件。","errorUserTitle":"Can't Read Files"}

如您所见,我将图像存储在 firebase 数据库中(我将确切的 url 替换为 URL 以不在此处发布),在调用 Facebook 发布功能之前,图像已经上传并压缩,它位于 .jpg格式,因此 Facebook 帖子的错误消息不准确或对我没有帮助。除此之外,确切的代码在 iOS 上运行得非常好。

我正在寻找解决这个错误的方法几个小时,所以这里有人可以帮助我解决这个问题。以前有人遇到过这个问题并且可能知道解决方案吗?

编辑:

带有完整 URL 的 console.log:

iOS:

/me/photos?method=post&url=https://firebasestorage.googleapis.com/v0/b/appname-50cd0.appspot.com/o/post%252F-KbyHksSP_EV2MTjvCb5.jpg?alt=media&token=64f43c60-47fa-40b2-b85b-e1e5ae1dea13&caption=Rest

安卓:

/me/photos?method=post&url=https://firebasestorage.googleapis.com/v0/b/appname-50cd0.appspot.com/o/post%252F-KbxypBFRqs6eyYNk8ZR.jpg?alt=media&token=4420080a-41d8-4816-bf62-5bfb159d1da5&caption=FB

图片明显不同,但网址结构相同。

EDIT2:

到目前为止我尝试了什么:

  • 使用 Firebase 存储中现有图片的 URL,由 iOS 设备获取 -> 相同的错误。
  • 将 Android 哈希键添加到 facebook 开发环境 -> 相同的错误
  • 在 config.xml 中将 graph.facebook.com 列入白名单:

    <access origin="*graph.facebook.com*" subdomains="true"/>
    

->同样的错误

  • 使用 encodeURIComponent(url) 而不是 encodeURI(url) -> 相同的错误

我正在使用带有 Android 6.0.1 的 Nexus 5 作为测试设备,目前我无法访问另一台 Android 设备,但我会尽快在另一台设备上试用它。

编辑 3:

  • 所以我在其他 2 台 Android 设备上对其进行了测试,结果确实出现了同样的错误

  • 我将 facebook4 插件更新到支持 facebook sdk 4.22.1 的最新版本,但错误仍然存​​在

  • 我尝试将 FB.init 函数(第 147 行)中的 cordova-plugin-facebook4/www/facebook-browser.js 中的版本从 2.7 版更改为 2.9 版(这是最新的),但出现错误遗骸

编辑 4 已解决

最后,解决方案在 cmets 中。当您使用包含参数字符的下载 url 时,这是 android 设备上的 cordova-plugin-facebook4 错误? & 和 =,firebase 存储的作用。

【问题讨论】:

  • 您能否验证facebookString 在Android 和iOS 上是否包含完全相同 相同的内容?
  • 我编辑了帖子并添加了 url 示例。据我所知,它们具有完全相同的结构,但图像不同,但我在两种设备上使用不同的图像进行了测试,结果始终相同。
  • 在这两种情况下,图像 URL 似乎都没有正确地进行 URL 编码(尽管,可能是复制和粘贴问题,具体取决于您从哪里得到它。)但 encodeURI 是在这里使用错误的方法 - 尝试改用encodeURIComponent,看看是否会产生不同的结果。 (它们对一组不同的字符进行编码 - 特别是 encodeURI 确实 not 包括 ?&amp;,而这些最需要编码。)
  • 使用 encodeURIComponent 时,URL 的编码方式不同,但它仍然会在 android 上引发相同的错误。我还尝试将链接硬编码到使用 iOS 设备制作的 firebase 中的图片的链接,来自 facebook 的相同错误。所以图像编码本身并不是错误源。我现在很茫然。
  • 有些人报告说,Facebook 偶尔会在通过 HTTPS 提供图像时遇到问题……但通过 HTTP 提供图像似乎不是一个选择(?)。虽然我不认为 Google 的 HTTPS 设置/证书会出现一般性问题,但通过一些 SSL 检查服务运行 URL 并查看这些服务是否报告任何问题可能不会有什么坏处。

标签: android angularjs facebook cordova facebook-graph-api


【解决方案1】:

已解决

经过数小时后,我发现了问题。 cordova-plugin-facebook4 与 firebase 存储的组合在 Android 上不起作用,因为插件内部的编码处理错误。

在cordova-plugin-facebook4/src/android/ConnectPlugin.java文件里面有这个函数:

private void makeGraphCall() {...}

此函数解码整个“facebookString”,然后按特殊字符对其段进行排序? & 和 =。 firebase 存储下载链接确实包含安全令牌的参数,因此此时插件会尝试将 firebase 变量解释为 facebook 参数并剪切 firebase url 的 url 参数。

我所做的是修改这部分功能:

for (String query : queries) {
  int splitPoint = query.indexOf("=");
  if (splitPoint > 0) {
    String key = query.substring(0, splitPoint);
    String value = query.substring(splitPoint + 1, query.length());
    params.putString(key, value);
  }
}

到:

for (String query : queries) {
  int splitPoint = query.indexOf("=");
  if (splitPoint > 0) {
    String key = query.substring(0, splitPoint);
    String value = query.substring(splitPoint + 1, query.length());
    if(key.equals("url") || key.equals("caption")){
      value = URLDecoder.decode(value);
    }
    params.putString(key, value);
  }
}

在角度部分,我对包含参数的原始 firebase URL 部分进行了编码,之后我再次解码了整个 URL,然后将其传递给 facebookstring。

我的 Angular 代码片段:

function makeCallToFacebookWithImage(url) {
  console.log("share to facebook with image");
  var newURL = url;
  var caption = $scope.comment;
  if (ionic.Platform.isAndroid()) { //prep only neccessary on android
    console.log("Is Android device");
    var index = url.indexOf("%2F"); //firebase link specific encoding for folders
    var leftSide = url.substring(0, index);
    var rightSide = url.substring(index, url.length);
    newURL = leftSide + encodeURIComponent(rightSide);
    caption = encodeURIComponent(caption);
  }
  newURL = encodeURIComponent(newURL);
  var facebookString = "/me/photos?method=post&url=" + newURL + "&caption=" + encodeURIComponent(caption);
...

我将就这个错误联系 facebook4 插件的开发人员。我希望这可以帮助其他可能陷入此特定错误的人。

【讨论】:

  • 这让我们回到我之前的评论,即 URL 未正确进行 URL 编码。如果是的话,这个问题一开始就不应该发生。而且我不会说这是插件中的一个错误(除非该插件首先构造了在其他地方自行分解的 URL。)对于解析查询字符串的所有其他语言/技术,它都是相同的问题。
  • 嗯,这确实是一个错误或实现错误。插件的 ios 代码正确解构了 facebookString,而 android java 代码以错误的方式拆分了字符串。它不认为 url 可能包含像 & 这样的特殊符号,如果你对字符串的 url 部分进行双重编码,它不会再次对其进行双重解码,因此 url 将无效。这就是为什么我必须对插件进行双重编码/解码修改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-20
  • 2019-06-11
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
  • 2019-02-12
相关资源
最近更新 更多