Javaのエンドポイントからadmin SDK経由でfirebase realtime dbにアクセスしようとしています。認証は成功したようですが、クエリは効果がありません。エラーは発生せず、リスナーは呼び出されません。 Firebaseルールは書き込み可能に設定されています(シミュレータで保証されています)。JavaのエンドポイントからFirebase admin
Firebase DB:
mydbid
+---users
+---user0
+---email:[email protected]
エンドポイントDEF:
@Api(
name = "firebaseTestEndpoint",
version = "v1",
description = "Firebase admin test endpoint.")
public class FirebaseTestService {
private static final Logger log =
Logger.getLogger(FirebaseTestService.class.getName());
static {
log.setLevel(Level.INFO);
}
@ApiMethod(httpMethod = HttpMethod.POST)
public void connectToFirebase(@Named("id") String id,
ServletContext servletContext) {
Map<String, Object> authVars = new HashMap<String, Object>();
authVars.put("uid", "admin");
try {
FirebaseOptions options = new FirebaseOptions.Builder()
.setDatabaseUrl("https://mydbid.firebaseio.com")
.setCredential(FirebaseCredentials.fromCertificate(
servletContext.getResourceAsStream(
"/WEB-INF/firebase-credentials.json")))
.setDatabaseAuthVariableOverride(authVars)
.build();
FirebaseApp app = FirebaseApp.initializeApp(options);
DatabaseReference ref =
FirebaseDatabase.getInstance().getReference("https://stackoverflow.com/users/user0/email");
ValueEventListener valueEventListener =
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot arg0) {
log.info(arg0.getRef().getPath().toString() +
" changed to " + arg0.getValue(String.class));
}
@Override
public void onCancelled(DatabaseError arg0) {
log.info("cancelled");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
@ApiMethod(httpMethod = HttpMethod.POST)
public void updateEmail(@Named("id") String id) {
Map<String,Object> values = new HashMap<String,Object>();
values.put("email", "[email protected]");
try {
FirebaseDatabase.getInstance().getReference("https://stackoverflow.com/users/user0")
.updateChildren(values, new DatabaseReference.CompletionListener() {
public void onComplete(DatabaseError databaseError,
DatabaseReference databaseReference) {
if (databaseError != null) {
throw databaseError.toException();
}
log.info("update completed.");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
のAppEngine-web.xmlの(関連部品):
<basic-scaling>
<max-instances>2</max-instances>
</basic-scaling>
のweb.xml(関連部品、宇宙*)の前に挿入:
<servlet>
<servlet-name>EndpointsServlet</servlet-name>
<servlet-class>com.google.api.server.spi.EndpointsServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>mypackage.FirebaseTestService</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>EndpointsServlet</servlet-name>
<url-pattern>/_ah/api/ *</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>mypackage.FirebaseTestService</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/ *</url-pattern>
</servlet-mapping>
APIのエクスプローラでテストされたconnectToFirebase()呼び出しのあとに、_ah/backgroundへのリクエストが続きますが、updateEmail()は必要ありません。 どうしたの?
データベースリスナーは別々のバックグラウンドスレッドで実行されます。リスナーが実行される前に、リクエストスレッドが返されます。あなたはそれらを待ってみて、違いがあるかどうか確認できますか?タスクAPIを使用して待機することができます:https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/tasks/Tasks –
Tasks.await(タスク)では、DEADLINE_EXCEEDEDエラーは戻ってきた。バックグラウンドスレッドがジョブを完了できないようです... –
Firebase SDKのバージョンを確認できますか?また、ThreadManager APIを使用して、インスタンスに実際にバックグラウンドスレッドがサポートされていることを確認することもできます。自分でバックグラウンドスレッドを作成して起動し、これを確認することもできます:https://cloud.google.com/appengine/docs/standard/java/runtime#background_threads_1 –