如何在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对象被提前回收,可从以下几点修复:
- 持有Listener的强引用
Python垃圾回收可能在Java回调触发前回收OnSuccessListener实例,导致Java侧调用空对象。需在全局或父对象中保存Listener引用:
# 用类成员或全局变量保存listener,避免被GC回收 self.token_listener = OnSuccessListener(complete_listener) user.getIdToken(False).addOnSuccessListener(self.token_listener)
- 正确处理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)
- 检查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对象无效")
- 线程安全的回调处理
若回调在非主线程触发,需切换到主线程执行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
相关产品推荐
相关产品推荐

