Query in Firebase database child - database

I'm new to android. Can someone help me to query the below-underlined line in the firebase? The query result should be the underlined String.
That String is an autogenerated one in the firebase at the Driver signup. So hardcoding that string is not my aim.

Refer to Users/Driver and loop through children, you will get your key:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child("Driver");
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//loop through the children
for(DataSnapshot ds: dataSnapshot.getChildren()){
//get the key or keys depending on how many keys
String underLinedKey = ds.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//log error
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
};
mDatabase.addValueEventListener(listener);

Related

Exception when trying to use DynamoDBMapper: no mapping for HASH key

I have a DynamoDB table with a primary key (id : integer) and secondary key (dateTo : String). I've made a Class that utilizes DynamoDBMapper:
#DynamoDBTable(tableName="MyItems"
public class MyItemsMapper {
private int id;
private String dateTo;
private String name;
#DynamoDBHashKey(attributeName="id")
public void setId(int id) { this.id = id; }
public int getId() { return id; }
#DynamoDBAttribute(attributeName="dateTo")
public void setDateTo(String dateTo) { this.dateTo = dateTo; }
public String getDateTo() { return dateTo; }
#DynamoDBAttribute(attributeName="name")
public void setName(String name { this.name = name; }
public String getName() { return name; }
public boolean saveItem(MyItemsMapper item) {
try {
DynamoDBMapper mapper = new DynamoDBMapper(client); //<-- This connects to the DB. This works fine.
item.setId(generateUniqueNumber()); //<-- This generates a unique integer. Also seems to work fine.
mapper.save(item);
logger.info("Successfully saved item. See info below.");
logger.info(item.toString());
return true;
} catch (Exception e) {
logger.error("Exception while trying to save item: " + e.getMessage());
e.printStackTrace();
return false;
}
}
}
I then have a manager class that uses the bean above, like so:
public class MyManager {
public boolean recordItem(
int id,
String dateTo,
String name,
) {
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
myItemsMapper.saveItem(myItemsMapper);
}
}
I am running the manager class in a JUnit test:
public class MyManagerTest {
#Test
public void saveNewItemTest() {
MyManager myManager = new MyManager();
myManager.recordItem(1234567, "2018-01-01", "Anthony");
}
}
When I use the saveItem method above via my manager by running my JUnit test, I get the following error:
com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: MyItemsMapper; no mapping for HASH key
Not really sure what it's pertaining to, as I definitely have a primary key for my table and my secondary key always has a value as well.
How do I get this to work?
More Info:
It's worth noting that I can record data into my DynamoDB table via the Item object. If I do the below, my data gets recorded into the database:
DynamoDB dynamoDB = new DynamoDBClient().connectToDynamoDB(); //<--
Connection. Works fine.
Table table = dynamoDB.getTable("MyItems");
item.withPrimaryKey("id", 1234567);
item.withString("dateTo", "2018-01-01");
item.withString("name", "Anthony");
PutItemOutcome outcome = table.putItem(item);
However, I'm trying to use DynamoDBMapper because I'm reading that it is a more organized, better way to access data.
Im not sure if this is causing the problem, but you are creating the myItemsMapper object, then passing a reference to this object to itself.
I would suggest removing your saveItem method. The MyItemsMapper class should be a plain old java object. Then make MyManager like this
public class MyManager {
public boolean recordItem(
int id,
String dateTo,
String name,
) {
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(myItemsMapper);
}
}
If you particularly want to keep the saveItem method make it like this
public boolean saveItem() {
try {
DynamoDBMapper mapper = new DynamoDBMapper(client);
mapper.save(this);
logger.info("Successfully saved item. See info below.");
logger.info(this.toString());
return true;
} catch (Exception e) {
logger.error("Exception while trying to save item: " + e.getMessage());
e.printStackTrace();
return false;
}
}
And then in MyManager do
MyItemsMapper myItemsMapper = new MyItemsMapper();
myItemsMapper.setId(id);
myItemsMapper.setDateTo(dateTo);
myItemsMapper.setName(name);
myItemsMapper.saveItem();

Read data from Firebase

I'm using Firebase for my Android app, I want read datas. In particular I want to select an user with a specific id. When I use the debugger it seems that the code doesn't execute the onDataChange() instruction.
private User readUserById(){
final User u = new User("","","");
Query query = mDatabaseReferences.child("users").orderByChild("id").equalTo(id);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
u.setId(ds.child("id").getValue(User.class).getId());
u.setNumber((ds.child("number").getValue(User.class).getNumber()));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return u;
}
private void initFirebase() {
FirebaseApp.initializeApp(this);
mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReferences = mFirebaseDatabase.getReference();
}
public void sendCode(View v){
id= id.getText().toString();
readUserById();
phoneNumber = phoneText.getText().toString();
if (phoneNumber.equals("") || id.equals("")) {
Toast t = Toast.makeText(this, "Please insert a nickname and a valid phone number", Toast.LENGTH_LONG);
t.show();
} else {
setUpVerificationCallbacks();
PhoneAuthProvider.getInstance().verifyPhoneNumber(
phoneNumber,
60,
TimeUnit.SECONDS,
this,
verificationCallbacks
);
}
// }
}
Using the debugger I've seen that the 'id' value is correct.
I used Firebase documentation for sendCode(), the user registration works correctly, just like the sms sending. I want to check if the nickname already exists, and the value is in the 'id' Textview. I call the sendCode() through a button.
I've tried in this way but doesn't work. Running with the debugger the result of user is null
private User readUserByName(){
final User[] user = {new User()};
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("users").child(nick).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
user[0] = dataSnapshot.getValue(User.class);
Log.d("Tag", user[0].toString());
}
else
Log.e("Tag","No such user exists");
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return user[0];
}
This is how I save the User
I've launched the app with the debugger
Assuming that users node is a direct child of your Firebase root, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference testRef = rootRef.child("users").child("test");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String id = dataSnapshot.child("id").getValue(String.class);
String idName = dataSnapshot.child("idName").getValue(String.class);
String number = dataSnapshot.child("number").getValue(String.class);
Log.d("TAG", id + " / " + idName + " / " + number);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
testRef.addListenerForSingleValueEvent(eventListener);
The output will be:
test / f70eb... / number
Assumed that :
node "users" directly under root node.
You already know the id of the user and this id contains all the information under User.class
You only want to read a user, if exists in database.
All the getters and setter exists in User.class and a Public empty constructor exists
Here is how you should do it
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("users").ref(id).addListenerforSingleValueEvent(listener);
And in Listener's OnDataChange(DataSnapshot snap);
if(snap.exists()){
user = snap.getValue(User.class);
Log.d("Tag",user.toString());
}
else
Log.e("Tag","No such user exists");

Store JSON Array from NewsAPI in Firebase

I have used volley to parse news data from the newsAPI.org. I want to save the response to Firebase for offline viewing and persistence.
This is the sample response from API:
articles: [
{
author: "Megan Rose Dickey",
title: "Ojo wants to be the electric scooter for commuters, but...",
description: "Commuting in a busy city like San Francisco can be
annoying..",
url: "https://techcrunch.com/2017/08/23/ojo-wants-to-be-the-electric-
scooter-for-commuters-but-its-not-there-yet/",
urlToImage: "https://img.vidible.tv/prod/2017",
publishedAt: "2017-08-23T21:19:56Z"
},
{
author: "Katie Roof",
title: "Pishevar intervenes in Benchmark-Kalanick lawsuit",
description: "Early Uber investor and former board member Shervin
Pishevar is speaking out against Benchmark again..",
url: "https://techcrunch.com/2017/08/24/pishevar-sends-another-letter-
to-uber-board-about-benchmark/",
urlToImage:"https://tctechcrunch2011.files.wordpress.com/",
publishedAt: "2017-08-24T22:49:59Z"
},
In total I have 5 objects inside the articles array.
I want to store each of the objects in Firebase database. This is what I have tried:
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.NEWS_ENDPOINT,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response != null){
Log.d(TAG, "News Api Response is: \t" + response.toString());
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray articles = jsonObject.getJSONArray("articles");
for (int i = 0; i < articles.length(); i++){
JSONObject items = articles.getJSONObject(i);
final String title_news = items.getString("title");
final String desc_news = items.getString("description");
final String urlImg = items.getString("urlToImage");
final String author_news = items.getString("author");
final String url = items.getString("url");
final String publishedAt = items.getString("publishedAt");
NewsItem newsItem = new NewsItem(author_news, title_news, desc_news, url, urlImg, publishedAt);
itemList.add(newsItem);
/**
* Save JSON Results to Firebase
* */
for (int k = 0; k < articles.length(); k++){
HashMap hashMap = new HashMap();
hashMap.put("newsTitle", title_news);
hashMap.put("newsDesc", desc_news);
hashMap.put("newsImageUrl", urlImg);
hashMap.put("newsAuthor", author_news);
hashMap.put("newsUrl", url);
hashMap.put("newsDate", publishedAt);
newsRootRef.setValue(hashMap);
}
When I check the console, it saves only one object, the last object like this:
I want to store all objects AS-IS in the response array and retrieve them later. Is there another way to do this? Thanks, sorry for the long post.
In this case you need to use push() to store the data. Otherwise you are just replacing the data at the reference at each iteration. This is why it seems that only the last record gets stored. Try to change this line:
newsRootRef.setValue(hashMap);
...into this:
newsRootRef.push().setValue(hashMap);
To avoid duplicating entries I recommend that you fetch all entries from Firebase and cache the url property (since this property seems to be unique) in a HashSet. Then you can modify your code like this:
if (!urlSet.contains(url)) {
HashMap hashMap = new HashMap();
hashMap.put("newsTitle", title_news);
hashMap.put("newsDesc", desc_news);
hashMap.put("newsImageUrl", urlImg);
hashMap.put("newsAuthor", author_news);
hashMap.put("newsUrl", url);
hashMap.put("newsDate", publishedAt);
newsRootRef.push(),setValue(hashMap);
}
But of course you need to populate your HashSet first so I'd recommend doing something like this:
final Set<String> urlSet = new HashSet<>();
newsRootRef.addChildEventListener(new ChildEventListener() {
int i = 0;
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
urlSet.add(dataSnapshot.getValue(String.class));
if (i++ == dataSnapshot.getChildrenCount()) {
...
...your code...
StringRequest stringRequest = new StringRequest(Request.Method.GET, Constants.NEWS_ENDPOINT,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
...
...
}
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

loaderManager recyclerview imageview viewholder content provider fails

I am new at android and new at posting here and trying a sink in slowly but am stuck here at inflating imageViews. Below am providing code snippets from my app that i would thank you for your help
Here is my table
private static final String CREATE_TABLE = "CREATE TABLE "+TABLE_NAME+" ("+KEY_ID,"+KEY_PROFILEPIC+" BLOB,"+KEY_IMAGE+" BLOB)";
this is my viewholder class
`public CityHolder(final View view) {
super(view);
ButterKnife.bind(this, itemView); }
public void bindData(final Cursor cursor) {
String name = cursor.getString(cursor.getColumnIndex("name"));
this.name.setText(name);
String CircularNetWorkImageView =cursor.getString(cursor.getColumnIndex("profilePic"));
this.CircularNetWorkImageView.setText(CircularNetWorkImageView);
}
`
and then i am using recyclerview to bind to cursor.
am also using a a content Provider to both insert and then retrieve data and load by use of the LoaderManager.LoaderCallbacks
here is how i get the data through volley json
JSONArray jsonArray = response.getJSONArray("city");
for (int i=0;i<jsonArray.length();i++)
{
JSONObject jsonObjectCity = jsonArray.getJSONObject(i);
String name = jsonObjectCity.getString("name");
String profilePic = jsonObjectCity.getString("profilePic");
String image = jsonObjectCity.getString("image");
City city = new City();
city.setName(name);
city.setProfilePic(profilePic);
city.setImage(image);
ContentValues values = new ContentValues();
values.put(CityDb.KEY_NAME, name);
values.put(CityDb.KEY_PROFILEPIC, profilePic);
values.put(CityDb.KEY_IMAGE, image);
getContentResolver().insert(CityContentProvider.CONTENT_URI, values);
}
}catch(JSONException e){e.printStackTrace();}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley","Error");
}
}
);
requestQueue.add(jor);
}
#Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
String[] allColumns = new String[] {
CityDb.KEY_ID,
CityDb.KEY_NAME,
CityDb.KEY_PROFILEPIC,
CityDb.KEY_IMAGE
};
return new CursorLoader(this,CityContentProvider.CONTENT_URI,allColumns, null, null, null);
}`
Now the String Name is displayed in my fragment but am having issue getting the image and profilePic in circularNetworkimageView to display.
what could i be missing, please guide me

Suggest Addresses in a SuggestBox in GWT/Java

I want to define a SuggestBox, which behaves like the search bar in Google Maps: When you begin to type, real addresses, starting with the typed letters, appear.
I think, that I need to use the Geocoder.getLocations(String address, LocationCallback callback) method, but I have no idea how to connect this with the oracle, which is needed by the suggest box to produce its suggestions.
Can you please give me ideas how do I connect the getLocations Method with the SuggestOracle?
I solved this by implementing a subclass of SuggestBox, which has it's own SuggestOracle. The AddressOracle deals as a Wrapper for the Google Maps Service, for which the class Geocoderin the Google Maps API for GWT offers abstractions.
So here is my solution:
First we implement the Widget for a SuggestBox with Google Maps suggestions
public class GoogleMapsSuggestBox extends SuggestBox {
public GoogleMapsSuggestBox() {
super(new AddressOracle());
}
}
Then we implement the SuggestOracle, which wraps the Geocoder async method abstractions:
class AddressOracle extends SuggestOracle {
// this instance is needed, to call the getLocations-Service
private final Geocoder geocoder;
public AddressOracle() {
geocoder = new Geocoder();
}
#Override
public void requestSuggestions(final Request request,
final Callback callback) {
// this is the string, the user has typed so far
String addressQuery = request.getQuery();
// look up for suggestions, only if at least 2 letters have been typed
if (addressQuery.length() > 2) {
geocoder.getLocations(addressQuery, new LocationCallback() {
#Override
public void onFailure(int statusCode) {
// do nothing
}
#Override
public void onSuccess(JsArray<Placemark> places) {
// create an oracle response from the places, found by the
// getLocations-Service
Collection<Suggestion> result = new LinkedList<Suggestion>();
for (int i = 0; i < places.length(); i++) {
String address = places.get(i).getAddress();
AddressSuggestion newSuggestion = new AddressSuggestion(
address);
result.add(newSuggestion);
}
Response response = new Response(result);
callback.onSuggestionsReady(request, response);
}
});
} else {
Response response = new Response(
Collections.<Suggestion> emptyList());
callback.onSuggestionsReady(request, response);
}
}
}
And this is a special class for the oracle suggestions, which just represent a String with the delivered address.
class AddressSuggestion implements SuggestOracle.Suggestion, Serializable {
private static final long serialVersionUID = 1L;
String address;
public AddressSuggestion(String address) {
this.address = address;
}
#Override
public String getDisplayString() {
return this.address;
}
#Override
public String getReplacementString() {
return this.address;
}
}
Now you can bind the new widget into your web page by writing the following line in the onModuleLoad()-method of your EntryPoint-class:
RootPanel.get("hm-map").add(new GoogleMapsSuggestBox());

Resources