【问题标题】:Get information from Firebase Realtime Database with Firebase Admin SDK使用 Firebase Admin SDK 从 Firebase 实时数据库获取信息
【发布时间】:2018-10-13 16:12:00
【问题描述】:

我试图从 Firebase 实时数据库中获取一些信息,但没有成功。我不知道我做错了什么。我还尝试了文档的示例,但它们没有用。这是我的代码和我的 firebase db 结构:

Topics.java:

public class Topics {

 private String name;

 public Topics() {

 }

 public Topics(String name) {
    this.name = name;
 }

 public String getName() {
    return name;
 }

 public void setName(String name) {
    this.name = name;
 }

}

Main.java

public static void main(String[] args) {
    // TODO Auto-generated method stub
    FileInputStream serviceAccount;
    FirebaseOptions options = null;
    try {
        serviceAccount = new FileInputStream(".//...");
        options = new FirebaseOptions.Builder()
                .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                .setDatabaseUrl("...")
                .build();

    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch(IOException e) {
        e.printStackTrace();
    }

    FirebaseApp.initializeApp(options);
    String topics = getDatafromFirebase();

    System.out.println("Everything right!");
}

private static String getDatafromFirebase() {
    CountDownLatch done = new CountDownLatch(1);
    StringBuilder b = new StringBuilder();
    DatabaseReference dbRef = FirebaseDatabase.getInstance()
            .getReference();

    dbRef.child("topics").addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot snapshot) {
            // TODO Auto-generated method stub
            if(snapshot.exists()) {
                for(DataSnapshot s:snapshot.getChildren()) {
                    Topics t = s.getValue(Topics.class);
                    b.append(t.getName());
                    b.append(" ");
                    done.countDown();
                }
            }
            else {
                b.append("No existe ");
                done.countDown();
            }

        }

        @Override
        public void onCancelled(DatabaseError error) {
            // TODO Auto-generated method stub
            b.append("Error: "+error.getDetails());
            done.countDown();
        }
        });
    try {
        done.await();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return b.toString();
}

我已经等待CountDownLatch 等待5+ 分钟,我认为这足以触发它。另外,重要说明:我已通过 Firebase 云消息传递成功发送消息,因此我认为这不是凭据问题。

【问题讨论】:

  • 乍一看,代码对我来说很好。如果在onDataChange 中设置断点,会触发吗?
  • @FrankvanPuffelen 在onDataChangeonCancelled 中都设置了断点。它们不会被触发。
  • 发生这种情况的唯一原因是客户端永远无法从服务器获得答案。这可能会发生(根据我的经验),因为客户端没有互联网连接,或者因为客户端在数据从服务器返回之前退出。
  • 另一个原因可能是凭据设置不正确。如果您的计算机的 SHA 密钥正确,请检查 firebase 控制台。当您说您使用 FirebaseCloudMessaging 时,您的意思是在这段代码中?
  • @Juanje 如何检查 firebase 和我的计算机中的 SHA 密钥?不是我的问题中的代码。我编写了一个方法,使用相同的 Firebase 初始化(相同的凭据、相同的数据库 URL 等)向我的应用发送通知。

标签: java firebase firebase-realtime-database


【解决方案1】:

我使用相同的数据库结构对我的数据库运行了您的代码,我可以肯定地说我能够从数据库中获取信息。

onDataChange 断点只有在我完全删除 topics 子树时才会触发。 IE。在您的情况下是一个空数据库。

我怀疑您的数据库 url 或私钥 JSON。

按照以下说明获取新的私钥

  1. 在控制台中,点击左侧的齿轮图标,然后点击服务帐户标签 Refer

  2. 记下databaseUrl并点击Generate New Private Key,保存。 Refer

这是示例的工作代码

package fireb;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;

import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;


public class Fireb {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        FileInputStream serviceAccount;
        FirebaseOptions options = null;
        try {
            serviceAccount = new FileInputStream("C:\\key\\testapp-f0fe2-firebase-adminsdk-4po4a-5ce6c60b81.json");
            options = new FirebaseOptions.Builder()
                    .setCredentials(GoogleCredentials.fromStream(serviceAccount))
                    .setDatabaseUrl("https://testapp-f0fe2.firebaseio.com")
                    .build();

        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch(IOException e) {
            e.printStackTrace();
        }

        FirebaseApp.initializeApp(options);
        String topics = getDatafromFirebase();
        System.out.println(topics);
        System.out.println("Everything right!");
    }

    private static String getDatafromFirebase() {
        CountDownLatch done = new CountDownLatch(1);
        StringBuilder b = new StringBuilder();
        DatabaseReference dbRef = FirebaseDatabase.getInstance()
                .getReference();

        dbRef.child("topics").addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot snapshot) {
                // TODO Auto-generated method stub
                if(snapshot.exists()) {
                    for(DataSnapshot s:snapshot.getChildren()) {
                        Topics t = s.getValue(Topics.class);
                        b.append(t.getName());
                        b.append(" ");
                    }
                    done.countDown();
                }
                else {
                    b.append("No existe ");
                    done.countDown();
                }

            }

            @Override
            public void onCancelled(DatabaseError error) {
                // TODO Auto-generated method stub
                b.append("Error: "+error.getDetails());
                done.countDown();
            }
            });
        try {
            done.await();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b.toString();
    }
}

【讨论】:

  • 这并从数据库中删除所有项目然后重新创建然后再次使代码工作!
【解决方案2】:

根据可用的文档here

在您可以使用 Firebase Admin SDK 从服务器访问 Firebase 实时数据库之前,您必须使用 Firebase 对您的服务器进行身份验证。当您对服务器进行身份验证时,而不是像在客户端应用中那样使用用户帐户的凭据登录,而是使用向 Firebase 标识您的服务器的服务帐户进行身份验证。

如果您没有在服务器上运行您的代码,您可以按照here 的描述作为客户端进行身份验证。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2021-07-01
    • 1970-01-01
    • 2020-04-15
    • 2019-10-22
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 2020-04-12
    相关资源
    最近更新 更多