如何解决关于导出Firebase Messaging服务实现的Android lint投诉?

46
根据Google的开发者指南在我的应用程序中实现Firebase,我注意到Android Lint会发出警告。

思路是我们必须实现两个继承自Firebase服务的服务:

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { ... }

public class MyFirebaseMessagingService extends FirebaseMessagingService { ... }

然后在清单文件中注册这些服务。但是,它并不完美。特别是,这两个推荐的AndroidManifest.xml服务条目不包含任何特殊权限:

and then register those services in the manifest. But, it's not quite perfect. In particular, these two recommended AndroidManifest.xml service entries do not contain any special permissions:


<service android:name=".MyFirebaseMessagingService">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT"/>
    </intent-filter>
</service>

<service android:name=".MyFirebaseInstanceIDService">
    <intent-filter>
        <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
    </intent-filter>
</service>

因此,代码检查工具提示:

导出服务(指设置了exported=true或包含intent-filter但未指定exported=false的服务)应定义实体必须拥有的权限才能启动服务或绑定到其上。如果没有这个权限,任何应用程序都可以使用此服务。

那么我只需向每个服务标签添加此属性,就可以完成吗?

tools:ignore="ExportedService"

还有没有更好的方法来处理这种情况?我的意思是,像这样暴露这些特定的Firebase衍生服务是否安全?


2
如果设置exported=true,linter希望定义权限。我也想看到一个完整的答案,涉及到这个问题! - Westy92
2个回答

57
你问:...将这些特定的 Firebase 衍生服务暴露出来是否安全? 如果你信任这些服务的清单文件中的注释,那么是安全的。
在 Android Studio 中打开你的应用的 AndroidManifest.xml 文件。在窗口底部,选择 Merged Manifest 选项卡。滚动查找 FirebaseMessagingService 条目。双击包含服务名称的行。服务的清单文件应该会打开,然后你会看到以下内容:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.google.firebase.messaging">
    <uses-sdk android:minSdkVersion="14"/>

    <application>

        <!-- FirebaseMessagingService performs security checks at runtime,
             no need for explicit permissions despite exported="true" -->
        <service android:name="com.google.firebase.messaging.FirebaseMessagingService" android:exported="true">
            <intent-filter android:priority="-500">
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

    </application>
</manifest>

注意注释:FirebaseMessagingService在运行时执行安全检查,尽管exported =“true”,但无需显式权限。

您可以对FirebaseInstanceIdService执行相同操作,并查看相同的注释。

如果您信任注释(我信任),则可以安全地忽略lint警告或禁用检查。


7
我不知道"Merged Manifest"按钮!谢谢你! - AutonomousApps
我们已经设置了 android:exported="false",但我仍然收到通知。 不确定 Firebase 是否真的需要它们被导出。 - Prakash
2
有没有任何实际的解释来证明这些评论?你可能会相信它,但我们为什么要相信呢? - deed02392
FirebaseMessagingService 在运行时执行安全检查,但设置为未导出以明确避免允许另一个应用程序调用它。这就是今天该注释的含义。 - Hawklike

7
<service android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

根据官方代码示例,将exported=false设置为安全的选择。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接