Я впервые пробую использовать Firebase, и у меня возникла проблема. Получение данных из моего хранилища / базы данных Firebase работает только в том случае, если метод получения соответствует имени переменной или переменные-члены являются общедоступными. Но мое соглашение об именах для переменных-членов - mVariableName, и я оставляю "m" вне имени моего метода получения. Теперь у меня несколько вопросов:

Является ли публикация переменных-членов модели жизнеспособным вариантом или это плохая практика? Какой здесь лучший подход к именованию? Должен ли я назвать методы получения getmName или оставить «m» в именах переменных-членов? Должен ли я изменить его для всего проекта или только для этого класса? Я просто хочу знать, какие здесь лучшие практики.

Это класс, который читает записи:

public class ImagesActivity extends AppCompatActivity {

private RecyclerView mRecyclerView;
private ImageAdapter mAdapter;

private FirebaseStorage mFirebaseStorage;
private DatabaseReference mDatabase;
private List<Upload> mUploads;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_show_images);

    mRecyclerView = findViewById(R.id.recycler_view);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

    mUploads = new ArrayList<>();

    mFirebaseStorage = FirebaseStorage.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference(Constants.DATABASE_PATH_UPLOADS);

    mDatabase.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
                Upload upload = postSnapshot.getValue(Upload.class);
                Log.i("UPLOAD", "Upload : " + upload.getName());
                mUploads.add(upload);
            }

            mAdapter = new ImageAdapter(getApplicationContext(), mUploads);

            mRecyclerView.setAdapter(mAdapter);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });
}
}

И вот правила:

База данных:

{
  "rules": {
    ".read": true,
    ".write": true
  }
}

Место хранения:

service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}

И Upload.class (работает только в том случае, если либо поля являются общедоступными, либо имена методов получения соответствуют m-соглашению, что уродливо):

public class Upload {

    public String mName;
    public String mImageUrl;

    public Upload() {
    }

    public Upload(String name, String imageUrl) {
        if (name.trim().equals("")) {
            name = "No Name";
        }

        mName = name;
        mImageUrl = imageUrl;
    }


    public String getName() {
        return mName;
    }

    public String getImageUrl() {
        return mImageUrl;
    }
}
0
Florian Walther 30 Дек 2017 в 21:49

2 ответа

Лучший ответ

Лучше всего использовать стандартный POJO или простой старый объект Java. Если вы это сделаете, Firebase уйдет с вашего пути:

public final class User {
    // These names don't matter since they are private, you could call it `glubustufo` 😁
    // They should always be private
    private String mName;
    private String mEmail;
    // ...

    // Constructors

    // Methods should be public and use the get/set convention where the following
    // words are in CamelCase and will be translated to lowerCamelCase in the db.
    public String getName() { return mName; }

    public void setName(String name) { mName = name; }

    public String getEmail() { return mEmail; }

    public void setEmail(String email) { mEmail = email; }

    // equals, hashCode, toString
}

Изменить , используйте этот класс:

public final class Upload {
    private String mName;
    private String mImageUrl;

    public Upload() {
        // Needed for Firebase reflection
    }

    public Upload(String name, String imageUrl) {
        if (name.trim().equals("")) {
            name = "No Name";
        }

        mName = name;
        mImageUrl = imageUrl;
    }

    public String getName() {
        return mName;
    }

    public void setName(String name) {
        mName = name;
    }

    public String getImageUrl() {
        return mImageUrl;
    }

    public void setImageUrl(String url) {
        mImageUrl = url;
    }
}
4
SUPERCILEX 30 Дек 2017 в 19:38

В качестве альтернативы отличному ответу Supercilex вы также можете использовать класс с только общедоступными полями (а не с геттерами / сеттерами):

public final class Upload {
    public String name;
    public String imageUrl;
}

В этой ситуации Firebase будет искать (или создавать) свойство JSON, которое точно соответствует имени поля, поэтому убедитесь, что вы правильно написали его заглавными буквами.

Клиент Firebase создает экземпляр этого класса, ища конструктор без параметров. В этом тривиальном классе нет конструктора, поэтому компилятор Java / Android сгенерирует для вас конструктор по умолчанию без параметров. Если вы добавляете собственный конструктор, обязательно добавьте конструктор без параметров (как в ответе Supercilex).

Смотрите также:

2
Frank van Puffelen 31 Дек 2017 в 01:03