Retrofit post using Firebase

2019-01-18 23:16发布

问题:

Please any one please help. This is My API method

@POST("/user/new.json")
Call createUser(@Body User user);

This is my call in MainActivity

 Retrofit retrofit=new Retrofit.Builder().baseUrl("https://XXXXXX.firebaseio.com").addConverterFactory(GsonConverterFactory.create()).build();

    Api api=retrofit.create(Api.class);

    User user=new User(1,"Sam");

    Call<User> call=api.createUser(user);
    call.enqueue(new Callback<User>() {
        @Override
        public void onResponse(Call<User> call, Response<User> response) {
            Log.d("sam","run");
        }

        @Override
        public void onFailure(Call<User> call, Throwable t) {
            Log.d("sam","error");
        }
    });

This is User.java

public class User {

        int id;

        String name;

        public User(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }

Output is coming like that :-

"user" : {"new" : {"-KBgcQTomo8xGpnv5raM" : {"id" : 1,"name" : "Sam"}}}

But i want output like that :-

"user" : {"new" : {"id" : 1,"name" : "Sam"}}

Here is Tutorial For Retrofit + Firebase

please help................

回答1:

In firebase, when you POST you are attempting to push to a list of data stored under the POST's URL. Consequently, it is impossible to POST to /user/new.json and not store the data under a new firebase generated key like "-KBgcQTomo8xGpnv5raM" beneath /user/new.

If you want complete control of where you are putting the data you must use PUT. However, putting your new entry directly as /user/new would not make sense. Where will subsequent entries go?

If you are not accepting server side keys assignment, then the normal solution would be to use some part of the entry that you will enforce uniqueness on. For example, either the name or numeric id could be the key for the new user so that multiple users may be added.

Based on the retrofit API and using name as the unique key, this:

@POST("/user/new.json")
Call createUser(@Body User user);

would become:

@PUT("/user/new/{name}.json")
Call createUser(@Path("name") String name, @Body User user);

and:

Call<User> call=api.createUser(user);

would then be:

Call<User> call=api.createUser(user.name, user);

now the layout would be:

"user" : {"new" : {"Sam": {"id" : 1,"name" : "Sam"}}}

so future users could be added as long as they were not named Sam.



回答2:

I don't think you have to use Retrofit to post data.

There is Way to Saving data in Firebase. May you know that Firebase managing all the thing in background itself.

I don't know why are you posting data using Retrofit.

Snippet to send and update automatically.

public class User {
    private int birthYear;
    private String fullName;

    public User() {}

    public User(String fullName, int birthYear) {
        this.fullName = fullName;
        this.birthYear = birthYear;
    }

    public long getBirthYear() {
        return birthYear;
    }

    public String getFullName() {
        return fullName;
    }
}

Firebase alanRef = ref.child("users").child("alanisawesome");

User alan = new User("Alan Turing", 1912);

alanRef.setValue(alan);

You can also save data directly to a database location:

//Referencing the child node using a .child() on it's parent node alansRef.child("fullName").setValue("Alan Turing"); alansRef.child("birthYear").setValue(1912);

It will save as you want:

{
  "users": {
    "alanisawesome": {
      "birthYear": "1912",
      "fullName": "Alan Turing"
    }
  }
}

Please follow the docs: Saving Data in Firebase

Thank you.



回答3:

As @sushildlh said it's not really worth to use retrofit in this case (if we are thinking about request send / respond timers), but it's good android programming practice. And I'm sure that you should still use retrofit.

But it's not the point. Your problem is in your API on the firebase. Create your own json file with a response that you want to get and upload it on the firebase.

Cheers