【问题标题】:Firebase admin from an endpoint in Java来自 Java 端点的 Firebase 管理员
【发布时间】:2017-09-28 16:36:29
【问题描述】:

我正在尝试通过管理 SDK 从 Java 端点访问 firebase 实时数据库。认证好像成功了,但是查询没有效果。不会发生错误,也不会调用侦听器。 Firebase 规则设置为可写(通过模拟器保证)。

Firebase 数据库:

    mydbid
      +---users
           +---user0
                +---email:default@gmail.com

端点定义:

    @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("/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", "updated@gmail.com");
    try {
        FirebaseDatabase.getInstance().getReference("/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>

在 APIs Explorer 中测试,connectToFirebase() 调用后跟对 _ah/background 的请求,但 updateEmail() 没有。 怎么了?

【问题讨论】:

  • 数据库监听器在不同的后台线程上运行。您的请求线程将在侦听器执行之前返回。您可以尝试等待他们,看看是否有什么不同?您可以使用 Tasks API 进行等待:firebase.google.com/docs/reference/admin/java/reference/com/…
  • 使用 Tasks.await(task),返回 DEADLINE_EXCEEDED 错误。后台线程似乎无法完成它的工作......
  • 您能确认您的 Firebase SDK 版本吗?并且还可以使用 ThreadManager API 来确保您的实例确实具有后台线程支持。您可以自己创建并启动一个后台线程来验证这一点:cloud.google.com/appengine/docs/standard/java/…
  • 另外,请尝试删除以下行的代码:authVars.put("uid", "admin")。这将帮助我们排除由 Firebase DB 规则引起的奇怪超时的情况。
  • Firebase 管理员的版本是 4.1.7。删除 .setDatabaseAuthVariableOverride(authVars) 没有效果。ThreadManager#createBackgroundThread(Runnable) 效果很好。

标签: java firebase firebase-realtime-database google-cloud-endpoints firebase-admin


【解决方案1】:

为了能够在 AppEngine 上使用 firebase 侦听器,请将基本缩放更改为手动缩放。

<manual-scaling>
   <instances>1</instances>
</manual-scaling>

如果您想使用 AppEngine 实例的基本或自动缩放功能,请将 firebase 侦听器更改为 REST 调用。

【讨论】:

  • 谢谢,但没有效果。
猜你喜欢
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
相关资源
最近更新 更多