You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中实现Firebase用户idToken获取的OnSuccessListener?

问题:使用Jnius在Python中获取Firebase idToken时出现段错误

我尝试获取Firebase用户的idToken,参考Firebase官方文档的Java实现:

Java官方示例代码

user.getIdToken(true).addOnSuccessListener(new OnSuccessListener<GetTokenResult>() {
  @Override
  public void onSuccess(GetTokenResult result) {
    String idToken = result.getToken();
    // 执行后续操作
    Log.d(TAG, "GetTokenResult result = " + idToken);
  }
});

我用Python基于Jnius实现的代码如下:

user.getIdToken(False).addOnSuccessListener(OnSuccessListener(complete_listener))


class OnSuccessListener(PythonJavaClass):
    __javainterfaces__ = ["com/google/android/gms/tasks/OnSuccessListener"]
    __javacontext__ = "app"

    def __init__(self, success_listener):
        self.success_listener = success_listener

    @java_method("(Ljava/lang/Object;)V")
    def onSuccess(self, result):
        print("Success.")

运行时触发段错误,错误日志如下:

12-11 11:33:52.714 20787 20787 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8f
12-11 11:33:52.714 20787 20787 F DEBUG   : Cause: null pointer dereference
12-11 11:33:52.714 20787 20787 F DEBUG   :     x0  000000735f399a00  x1  000000736997f930  x2  0000007369d3d814  x3  0000000000000000
12-11 11:33:52.714 20787 20787 F DEBUG   :     x4  0000007377ef4070  x5  0000000000000000  x6  6e616c2f6176616a  x7  676e697274532f67
12-11 11:33:52.714 20787 20787 F DEBUG   :     x8  ffffffffffffffff  x9  00000073697ba000  x10 0000000000000007  x11 0000007369e8b578
12-11 11:33:52.714 20787 20787 F DEBUG   :     x12 b4000073d6f8afb0  x13 0000000000000000  x14 0000000000730065  x15 00000074720530e0
12-11 11:33:52.714 20787 20787 F DEBUG   :     x16 00000073697b5ed0  x17 0000007369dc1e48  x18 000000747383c000  x19 000000736339b1f0
12-11 11:33:52.714 20787 20787 F DEBUG   :     x20 00000072ffffa980  x21 00000073000d5030  x22 00000073787cf100  x23 00000073000161a0
12-11 11:33:52.714 20787 20787 F DEBUG   :     x24 0000007377ef00d0  x25 0000007369649da0  x26 0000007369965940  x27 00000072ffff2390
12-11 11:33:52.714 20787 20787 F DEBUG   :     x28 0000007369e8ade8  x29 00000073000d51c0
12-11 11:33:52.714 20787 20787 F DEBUG   :     lr  0000007369797220  sp  0000007fc17b1470  pc  00000073697965ec  pst 0000000020000000
12-11 11:33:52.867 20787 20787 F DEBUG   : backtrace:
12-11 11:33:52.867 20787 20787 F DEBUG   :     NOTE: Function names and BuildId information is missing for some frames due
12-11 11:33:52.867 20787 20787 F DEBUG   :     NOTE: to unreadable libraries. For unwinds of apps, only shared libraries
12-11 11:33:52.867 20787 20787 F DEBUG   :     NOTE: found under the lib/ directory are readable.
12-11 11:33:52.867 20787 20787 F DEBUG   :       #00 pc 00000000000545ec  /data/data/com.mediaanalyser.imagefinder/files/app/_python_bundle/site-packages/jnius/jnius.so
12-11 11:33:52.867 20787 20787 F DEBUG   :       #01 pc 000000000013bed4  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #02 pc 0000000000132564  /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+548) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #03 pc 0000000000196e94  /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+204) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #04 pc 0000000000303384  /apex/com.android.art/lib64/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+376) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #05 pc 00000000002fe49c  /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+884) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #06 pc 00000000006314a8  /apex/com.android.art/lib64/libart.so (MterpInvokeVirtual+868) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #07 pc 000000000012c814  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_virtual+20) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #08 pc 0000000000000908  [anon:dalvik-classes6.dex extracted in memory from /data/app/~~yI30Ut6h9yYWQVYr63zPBA==/com.mediaanalyser.imagefinder-5s5hGX70E_a153yUyFvxcA==/base.apk!classes6.dex] (org.jnius.NativeInvocationHandler.invoke+80)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #09 pc 0000000000633078  /apex/com.android.art/lib64/libart.so (MterpInvokeInterface+1840) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)
12-11 11:33:52.867 20787 20787 F DEBUG   :       #10 pc 000000000012ca14  /apex/com.android.art/lib64/libart.so (mterp_op_invoke_interface+20) (BuildId: e340fd2be931aeda9bdb5d0e3fb87559)

解决方法

段错误通常源于JNI层对象引用失效或Python对象被提前回收,可从以下几点修复:

  1. 持有Listener的强引用
    Python垃圾回收可能在Java回调触发前回收OnSuccessListener实例,导致Java侧调用空对象。需在全局或父对象中保存Listener引用:
# 用类成员或全局变量保存listener,避免被GC回收
self.token_listener = OnSuccessListener(complete_listener)
user.getIdToken(False).addOnSuccessListener(self.token_listener)
  1. 正确处理GetTokenResult类型
    显式导入GetTokenResult类,确保类型转换正确:
from jnius import autoclass
GetTokenResult = autoclass('com.google.firebase.auth.GetTokenResult')

修改onSuccess方法获取token:

@java_method("(Ljava/lang/Object;)V")
def onSuccess(self, result):
    # 转换为正确的类型
    token_result = GetTokenResult.cast(result)
    id_token = token_result.getToken()
    print(f"获取到idToken: {id_token}")
    self.success_listener(id_token)
  1. 检查user对象有效性
    确保调用getIdToken时用户已登录且user对象非空:
if user is not None and user.isSignedIn():
    self.token_listener = OnSuccessListener(complete_listener)
    user.getIdToken(False).addOnSuccessListener(self.token_listener)
else:
    print("用户未登录或user对象无效")
  1. 线程安全的回调处理
    若回调在非主线程触发,需切换到主线程执行Python逻辑(以Kivy为例):
from kivy.clock import Clock

@java_method("(Ljava/lang/Object;)V")
def onSuccess(self, result):
    token_result = GetTokenResult.cast(result)
    id_token = token_result.getToken()
    # 切到主线程处理回调
    Clock.schedule_once(lambda dt: self.success_listener(id_token), 0)

内容的提问来源于stack exchange,提问作者ohshit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 06:25:53