Firebase Admin SDK para Android, métodos no encontrados

Estoy comstackndo una aplicación de Android respaldada por una aplicación de Firebase, y me gustaría poder crear una cuenta de administrador que pueda editar o eliminar otras cuentas de usuario. Si entiendo correctamente, el Firebase Admin SDK debería permitirme hacer esto. Así que seguí las instrucciones aquí .

Para configurar el SDK de administrador en mi aplicación. Agregué lo siguiente a build.app:

compile 'com.google.firebase:firebase-admin:4.1.1' 

Y en mi clase de Aplicación, agregué esto:

 FileInputStream serviceAccount = null; try { serviceAccount = new FileInputStream("app/.json"); } catch (FileNotFoundException e) { e.printStackTrace(); } if (serviceAccount != null) { FirebaseOptions options = new FirebaseOptions.Builder() .setCredential(FirebaseCredentials.fromCertificate(serviceAccount)) .setDatabaseUrl("https://.firebaseio.com/") .build(); FirebaseApp.initializeApp(options); } 

Sin embargo, me está diciendo que:

  • No hay un método llamado setCredential () en FirebaseOptions.Builder, y
  • FirebaseApp.initializeApp () toma un objeto Contexto, no FirebaseOptions.

De acuerdo con los documentos, FirebaseOptions.Builder.setCredential() es un método nuevo, que reemplaza a la obsoleta FirebaseOptions.Builder.setServiceAccount() . Pero setServiceAccount() tampoco existe.

¿Que está pasando aqui?

No puedes usar Firebase Admin SDK en una aplicación de Android junto con las bibliotecas de cliente de Firebase Android. Los SDK proporcionan clases con exactamente el mismo paquete y nombre de clase, por lo que posiblemente no podrían usarlos al mismo tiempo (¿cómo sabría el comstackdor cuál creará en su aplicación?).

A modo de ejemplo, eche un vistazo al javadoc para FirebaseOptions Builder en la biblioteca del cliente de Android:

com.google.firebase.FirebaseOptions.Builder

Ahora mira la misma clase del java Admin SDK (ten en cuenta que la URL es diferente):

com.google.firebase.FirebaseOptions.Builder

Puedes ver por ti mismo que son cosas diferentes, a pesar de que tienen el mismo nombre. Por lo tanto, su comstackdor está mirando la definición del SDK de Android y no la definición del SDK de administración.

Como dijo Frank, probablemente no quieras usar la biblioteca de administración dentro de tu aplicación de Android. Si desea usar el SDK de administración, utilícelo desde un servidor que controle y haga que su aplicación Android se comunique con él si es necesario.

Ahora la clase FirebaseOptions tomada de otras dependencias, puede eliminar los componentes de firebase de otras dependencias de la siguiente manera usando la etiqueta de exclusión.

 compile 'com.google.firebase:firebase-admin:5.8.0' compile ('com.google.firebase:firebase-messaging:9.6.1'){ exclude module: 'firebase-common' } compile ('com.google.firebase:firebase-auth:9.6.1'){ exclude module: 'firebase-common' } compile ('com.google.firebase:firebase-database:9.6.1'){ exclude module: 'firebase-common' } compile ('com.firebase:firebase-client-android:2.5.0'){ exclude module: 'firebase-common' } 

Como dice la respuesta aceptada, no es una buena idea colocar Firebase Admin en su aplicación de Android que usa Firebase, porque hay clases con los mismos nombres.

Quería crear un token personalizado ( https://firebase.google.com/docs/auth/android/custom-auth ), así que terminé haciendo:

1) Cree una aplicación de servidor independiente sin UI.

 class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) finish() // Just end the app here. } }    

2) Agregue un servicio de intendencia a la aplicación de servidor y genere un token personalizado.

 class CustomTokenService : IntentService(CustomTokenService::class.java.simpleName) { // Runs in its own thread. override fun onHandleIntent(intent: Intent?) { // Initialize FirebaseApp only when not already initialized. try { FirebaseApp.getInstance() } catch (ex: IllegalStateException) { try { val inputStream = assets.open("serviceAccountKey.json") val options = FirebaseOptions.Builder(). setCredential(FirebaseCredentials.fromCertificate(inputStream)). setDatabaseUrl("https://YOUR_APP.firebaseio.com/"). build() FirebaseApp.initializeApp(options) inputStream.close() } catch (e: IOException) { e.printStackTrace() } } // In real life, you should verify ID/PW before creating custom token. val id = intent!!.getStringExtra("ID") val pw = intent.getStringExtra("PW") val additionalClaims = HashMap() additionalClaims.put("premiumAccount", true) FirebaseAuth.getInstance().createCustomToken(id, additionalClaims). addOnSuccessListener { customToken -> // Send custom token back to client. val resultReceiver = intent.getParcelableExtra(RESULT_RECEIVER) val bundle = Bundle() bundle.putString(CUSTOM_TOKEN, customToken) resultReceiver.send(Activity.RESULT_OK, bundle) } } } 

Tenga en cuenta que estoy devolviendo el token personalizado al cliente a través de “ResultReceiver”, pero puede usar otras formas, como “Messenger” o “BroadcastReceiver”.

3) Desde el cliente, comienzo el servicio que reside en la aplicación del servidor.

 String MYSERVER = "SERVER_ID"; // eg "com.domain.myserver" String CUSTOM_TOKEN_SERVICE = MYSERVER + ".CustomTokenService"; Intent intent = new Intent(); intent.putExtra("ID", ID); intent.putExtra("PW", PW); intent.putExtra(RESULT_RECEIVER, mResultReceiver); intent.setComponent(new ComponentName(MYSERVER, CUSTOM_TOKEN_SERVICE)); getContext().startService(intent); 

4) Cuando recibo el token personalizado de la aplicación del servidor, inicio sesión en Firebase.

 ResultReceiver resultReceiver = new ResultReceiver(new Handler()) { @Override protected void onReceiveResult(int resultCode, Bundle resultData) { String customToken = resultData.getString(CUSTOM_TOKEN); mFirebaseAuth.signInWithCustomToken(customToken); } }; Parcel parcel = Parcel.obtain(); resultReceiver.writeToParcel(parcel, 0); parcel.setDataPosition(0); mResultReceiver = ResultReceiver.CREATOR.createFromParcel(parcel); parcel.recycle(); 

5) Y los archivos de configuración de Gradle.

 buildscript { ext.kotlin_version = '1.2.21' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.0.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } } allprojects { repositories { google() jcenter() } } task clean(type: Delete) { delete rootProject.buildDir } --------------------------------------------------------------------------- apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { compileSdkVersion 26 defaultConfig { applicationId "org.solamour.myserver" minSdkVersion 14 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true javaCompileOptions { annotationProcessorOptions { includeCompileClasspath false } } resConfigs "auto" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } // Conflict with dependency 'com.google.code.findbugs:jsr305' in project ':app'. // Resolved versions for app (1.3.9) and test app (2.0.1) differ. configurations.all { resolutionStrategy.force 'com.google.code.findbugs:jsr305:2.0.1' // Or "1.3.9". } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" implementation 'com.android.support:appcompat-v7:26.1.0' implementation 'com.android.support.constraint:constraint-layout:1.0.2' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' implementation 'com.google.firebase:firebase-admin:4.1.6' implementation 'com.android.support:multidex:1.0.2' } 

La versión más alta de Firebase Admin que pude usar fue “4.1.6”; cualquier cosa posterior a eso implicó una gran cantidad de modificaciones en el archivo gradle (y eso tampoco terminó bien).