使用Firebase Admin SDK从Firebase实时数据库获取信息

时间:2018-10-13 16:12:00

标签: java firebase firebase-realtime-database

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

Database structure

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();
}

我等待CountDownLatch5+分钟,我认为这足以触发它。另外,重要的注意事项:我已经通过Firebase云消息传递成功发送了消息,因此我认为凭证没有问题。

2 个答案:

答案 0 :(得分:1)

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

onDataChange断点不会触发,仅当我完全删除topics子树时才会发生。即。您的情况是一个空数据库。

我怀疑您的数据库网址或私钥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();
    }
}

答案 1 :(得分:0)

根据可用的文档here

  

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

如果您不在服务器上运行代码,则可以按照here的说明作为客户端进行身份验证。

希望这会有所帮助。