2016年12月10日土曜日

[Firebase]Admin Database API -> 引数には何を指定する? Listを御一考

- 私の公開しているandroidアプリでFirebase Realtime Databaseを利用しています
- androidアプリからはイベントの開催情報を読み込むのみです(書き込みはしません)



- 開催情報は定期的にかわるのでFirebase Realtime Databaseの内容は都度更新していく必要があります
- 開催情報を.jsonにする単純なRubyスクリプトをつくってRaspberry piで定期実行させていました
- Firebase Realtime Databaseの更新は手動でインポートしていました……
- 当然ある日、インポートを忘れてしまいました……

- インポートまで自動化できないか調べてみました
- 以前からできたのでしょうが……

- 2016/11/09あたり? Bringing Firebase To Your Server からAdmin SDKというのが紹介されていてこれを使えばうまくいきそうです
- Admin SDKは、NODE.JSとJavaがあって私はNODE.JSがよくわからないのでJavaを使いました(まあどの言語もよくわからないのですが……)

- 詳しくはAdd the Firebase Admin SDK to your ServerGet StartedとかSave Data 等の公式ドキュメントを読んでいただいたほうが正確ですし確実だとおもいますのでそちらをご参照されてください

- 前置きが長くなりましたがなぜ私が記事にしようかとおもったかというと、DatabaseReference#setValue(Object) の引数がよくわかりませんでした
- 公式サンプルだとMap<String, User>になっていて、Mapのkeyを何にすればよいのでしょうか?

- 上の画像には0, 1, 2とか書いてありますが実際の.jsonにはそんなものはありません
- インポートしたあとにRealtime Databaseのほうでつけている? とかもおもいましたがエクスポートしてみて確認してみるとそんなものついていません
- とりあえずmap.put("0", event0); map.put("1", event1);みたいな感じで整数を連番でふってみるとうまくいきました!
- その後、 DatabaseReference#setValue(Object) リファレンスをよくみるとList<Object>もいけると書いてあります!
- 結局List<Event>を指定するとうまくいきました
- ほとんど公式サンプルとかわりありませんが部分的に貼っておきます
DatabaseReference#setValue(Object) を実行すると、DatabaseReferenceが指しているところ以下をすべて書き換えるようです(私はこれを望んでいるのでよかったです)


Map<String, Object> auth = new HashMap<>();
auth.put("uid", "my-service-worker");

FirebaseOptions options = new FirebaseOptions.Builder()
      .setDatabaseUrl("https://databaseName.firebaseio.com")
      .setServiceAccount(new FileInputStream("path/to/serviceAccountCredentials.json"))
      .setDatabaseAuthVariableOverride(auth)
      .build();

FirebaseApp.initializeApp(options);

DatabaseReference ref = FirebaseDatabase
      .getInstance()
      .getReference();

List<Event> events = ...;

DatabaseReference eventsRef = ref.child("events");
eventsRef.setValue(events);



@Setter // Project Lombok
@Getter // Project Lombok
public class Event {

    private String title;
    private String place;
    private String range;
    private long start;
    private long end;

    public Event() {
        super();
    }

    public Event(String title, String place, String range, long start, long end) {
        this();
        this.title = title;
        this.place = place;
        this.range = range;
        this.start = start;
        this.end = end;
    }
}