I am trying to add schema where i have list of ids and value as a date. but I am getting the schema like this:
.
But I want in place of 0 is userID and date as a object. Please have a look over my code:
final String idGroup = (StaticConfig.UID + System.currentTimeMillis()).hashCode() + "";
final String currentDate = DateFormat.getDateInstance().format(new Date());
Room room = new Room();
for (String id : listIDChoose) {
AddGroupUser addGroupUser = new AddGroupUser();
addGroupUser.date = currentDate;
addGroupUser.user = id;
room.member.add(addGroupUser);
}
room.groupInfo.put("name", gName);
room.groupInfo.put("admin", StaticConfig.UID);
room.groupInfo.put("avatar",image);
FirebaseDatabase.getInstance().getReference().child("group/" + idGroup).setValue(room).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
ToastMessage("Group Created");
}
});
How to change my object so that i can get the following result. Any help will be very grateful. Thanks!!
In your Room class you have a List< AddGroupUser>. And Firebase translates a List to zero-based indexes in the JSON format.
To be able to control the key, the list needs to become a Map<String, AddGroupUser>. Then you can set the key of each AddGroupUser that you put in the map.
room.members.put(id, addGroupUser);
Related
I am new to firebase so, please bear with me. I am making a registration using firebase realtime database in android studio. What I want to do is that when the user enters her firstname and lastname, the system will set the username for them by taking the first character of the firstname and concatenate it with the lastname.
Example:
Name: John Smith
Username: jsmith
There are cases that there would be a duplication for the username because there are so many names that starts with J with the lastname Smith. So what I want is to add an integer if the username already exist.
jsmith, jsmith1, jsmith2, etc...
I know I needed to add a loop but I just don't know how to construct it. Here is my code:
public void insertAccount(){
acctstatus.setText("Active");
accttype.setText("Employee");
final String status = acctstatus.getText().toString();
final String type = accttype.getText().toString();
final String lname = empLname.getText().toString();
final String fname = empFname.getText().toString();
final String newfname = fname.substring(0,1).toLowerCase();
final String newuname = newfname+lname.toLowerCase();
// empuname.setText(newuname);
// final String uname = empuname.getText().toString();
// String passw = UUID.randomUUID().toString().substring(0,5);
// emppassw.setText(passw);
// String newpassw = emppassw.getText().toString();
String newpassw = newuname;
//
final int num = 0;
accountFirebaseReference.orderByChild("acct_uname").equalTo(newuname)
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String username = newuname+num+1;
empuname.setText(username);
final String acctuname = empuname.getText().toString();
Toast.makeText(getApplicationContext(), "Username: "+acctuname, Toast.LENGTH_LONG).show();
}else{
String username = newuname;
empuname.setText(username);
Toast.makeText(getApplicationContext(), "Username: "+empuname, Toast.LENGTH_LONG).show();
}
}
final String acctuname = empuname.getText().toString();
final String acctpassw = empuname.getText().toString();
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//addAccount(newuname, newpassw, type, status);
}
merely a suggestion. If a username exists, add a 01, like this jDoe01,jDoe02.... then jDoe011, etc.
Then, if a document exists, get the index of that zero, (it will always exist)
you can use something like int index = yourUserNameFromFirebase.indexOf('0');
then, you can use that index to get the number from the document, through doing a substring:
String numberValue = yourUserNameFromFirebase.substring(index);
int countOfDuplicateNames = Integer.valueOf(numberValue);
then, you can simply increment countOfDuplicateNames and make a new user, just remember to always ensure that the 0 is there, as this is the only way to get a reference to the number.
to pseudo code it, your new username will be something like this:
initial + surname + '0' + countOfDuplicateNames+1
Note
Sorry this answer does not cater for starting at an index of 1 :D
I am using this method to store data in my firebase database:
First i store all the data in a Model Class, called SubjectDataModel,
then i get the push key from the firebase database.
and then i set value to that particular key.
Here is my code :
SubjectDataModel:
public class SubjectDataModel {
public String id;
public String dbName;
public String subName;
public String tagline;
public int preference;
public SubjectDataModel()
{
}
public SubjectDataModel(String id, String dbName, String subName, String tagline, int preference) {
this.id = id;
this.dbName = dbName;
this.subName = subName;
this.tagline = tagline;
this.preference = preference;
}
}
Then i use the following code to push it to the database and then i also store the key id locally.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Data");
String id = ref.push().getKey();
SubjectDataModel newSub = new SubjectDataModel(id, txt_dbName, txt_subName, txt_tagline, txt_preference);
ref.child(id).setValue(newSub);
Now imagine, later in time, i want to update this data,
so i have the key id stored, so i can access it, i also have edited all the other data locally, so now if i make a SubjectDataModel Object with that data and again do ref.child(id).setValue(newSub); with the stored id, will the data be updated ? Or is there any other method to do so ?
updateChildren() is the method you are looking for, refer this documentation Firebase Read and Write Data on Android
Here's an example from documentation...
private void writeNewPost(String userId, String username, String title, String body) {
// Create new post at /user-posts/$userid/$postid and at
// /posts/$postid simultaneously
String key = mDatabase.child("posts").push().getKey();
Post post = new Post(userId, username, title, body);
Map<String, Object> postValues = post.toMap();
Map<String, Object> childUpdates = new HashMap<>();
childUpdates.put("/posts/" + key, postValues);
childUpdates.put("/user-posts/" + userId + "/" + key, postValues);
mDatabase.updateChildren(childUpdates);
}
Okay, so i tried this and it works perfectly, like i expected it to. No need for me to use maps or anything. Simplest way to update data.
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Data");
SubjectDataModel newSub = new SubjectDataModel(idForUpdate, txt_dbName, txt_subName, txt_tagline, txt_preference);
ref.child(idForUpdate).setValue(newSub);
So here basically, i created the object with the required data, and pushed it back to the same id with which i created a node in the firebase database, so it updates that same node with the new values.
I need to get the string value from the node passcode in my Firebase database to compare with a user input, but unfortunately I am not able to get the value. This is the link to my firebase database in the below image.
This is my codes below:
final DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("pin_code");
mDatabase.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
String rface = (String) dataSnapshot.child("pincode").getValue();
if (rface.equals(userPassword) && !rface.equals("")){
Intent intent = new Intent(PinActivity.this, ProfileActivity.class);
startActivity(intent);
}
else {
if (rface.equals("") || rface.equals(null)){
// Creating new user node, which returns the unique key value
// new user node would be /users/$userid/
String userId = mDatabase.push().getKey();
// creating user object
Pin pin = new Pin(authUserId, userPassword);
mDatabase.child(userId).setValue(pin);
Intent intent = new Intent(PinActivity.this, ProfileActivity.class);
startActivity(intent);
}
else {
Toast.makeText(PinActivity.this,"Invalid PIN code", Toast.LENGTH_SHORT).show();
return;
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
This is the json code
{
"pin_code" : {
"id" : "TQYTo1NHNnhPJnOxhe1Vok3U6ic2",
"pincode" : "12345"
}
}
This FirebaseDatabase.getInstance().getReference("pin_code") does not refer to the node you're looking for. Most likely you know the id property, in which case you can get the node with:
DatabaseReference collection = FirebaseDatabase.getInstance().getReference("p...");
Query query = collection.orderByChild("id").equalTo("TQT...ic2");
query.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
for (DataSnapshot child: dataSnapshot.getChildren()) {
String rface = (String) child.child("pincode").getValue();
if (rface.equals(userPassword) && !rface.equals("")){
The changes I made:
On the first line we get the collection: the node under which you want to run a query. You struck out the name of that node in the screenshot, but it's the second line you marked.
In the second line we create a query on the id property of each child node under the collection.
In the onDataChange we added a loop. This is needed because a query against the Firebase Database will potentially have multiple results. So the dataSnapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result. We loop over dataSnapshot.getChildren() to handle those multiple results.
If there can ever only be one node with the same id, you should consider changing your data structure to use the id as the key of the node. So:
pin_codes
uid1: "pincode1"
uid2: "pincode2"
Your code then becomes significantly simpler, because you don't need to query for the user anymore. You can just directly read from the path:
DatabaseReference user = FirebaseDatabase.getInstance().getReference("pin_codes").child("TQT...ic2");
user.addListenerForSingleValueEvent(new com.google.firebase.database.ValueEventListener() {
#Override
public void onDataChange(com.google.firebase.database.DataSnapshot dataSnapshot) {
String rface = (String) dataSnapshot.getValue();
if (rface.equals(userPassword) && !rface.equals("")){
Try change this:
String rface = (String) dataSnapshot.child("pincode").getValue();
To this:
String rface = (String) dataSnapshot.child("pincode").getValue(String.class);
Use the following::
Object some = dataSnapshot.getValue();
String value = some.toString();
I am creating a chatting application for android. I am using Firebase Real time database for this purpose. This is how "chats" branch of database looks like :
There are unique ID's for chat rooms generated using Users unique ID's such as "513","675" etc. Inside theese chatrooms there are message objects which also have unique ID's and inside them they store information of the date message sent, name of the sender, and the text of the message. Constructor of Message object is as follows :
public Message(String text,String senderUID, Long date){
this.text = text;
this.senderUID = senderUID;
this.date = date;
}
This is how I generate Time for the each message and send them to firebase database.
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
calendar = Calendar.getInstance();
String second,hour,minute;
String time;
if(calendar.get(Calendar.SECOND)<10){
second = "0"+calendar.get(Calendar.SECOND);
}
else
{
second = ""+calendar.get(Calendar.SECOND);
}
if(calendar.get(Calendar.MINUTE)<10){
minute = "0"+calendar.get(Calendar.MINUTE);
}
else
{
minute = ""+calendar.get(Calendar.MINUTE);
}
if(calendar.get(Calendar.HOUR)<10){
hour = "0"+calendar.get(Calendar.HOUR);
}
else
{
hour = ""+calendar.get(Calendar.HOUR);
}
time = date + hour + minute + second;
Log.d("time",time);
Message message = new Message(messageEditText.getText().toString(), user.getDisplayName(), Long.valueOf(time));
chatRoomDatabaseRef.child(chatID).child(user.getUid() + generateRandomNumber()).setValue(message);
messageEditText.setText("");
}
});
Here is how I get the data from database with value event listener :
chatRoomDatabaseRef.child(chatID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Set<Message> set = new HashSet<Message>();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Message message = snapshot.getValue(Message.class);
set.add(message);
}
messageList.clear();
messageList.addAll(set);
Collections.sort(messageList, new Comparator<Message>() {
#Override
public int compare(Message o1, Message o2) {
return Long.valueOf(o1.date).compareTo(Long.valueOf(o2.date));
}
});
messageAdapter.notifyDataSetChanged();
messageListView.setSelection(messageAdapter.getCount() - 1);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
After I get the data from Firebase database I order them according to their date attribute and list them. Everything works fine but when I am filling messages' date attribute, it fills according to the local time on the phone because of that I can't sort the messages correctly. Time can differ device to device. I need to use a Time which is common and same for all the devices using my app. But I couldn't find a way.
Edit:
I still couldn't figure out but as a quick solution I created an object called sequence number in the database. I added one more attribute to the message constructor called sequence number. I read the sequence number from the database, give that number to the next message and increase the value in the database for the new messages. Then I order messages according to that number. It is not the best way to do that but it is something until I find a better way.
Try this
firebase
.database()
.ref("/.info/serverTimeOffset")
.on("value", function(offset) {
let offsetVal = offset.val() || 0;
let serverTime = Date.now() + offsetVal;
console.log("serverTime", serverTime);
});
Use as time
Message message = new Message(messageEditText.getText().toString(), user.getDisplayName(), ServerValue.TIMESTAMP);
and for retrieving it
private String getDate(long time) {
Calendar cal = Calendar.getInstance(Locale.ENGLISH);
cal.setTimeInMillis(time);
String date = DateFormat.format("dd-MM-yyyy", cal).toString();
return date;
}
Above is my firebase database:
-Ideas
--Key generated by firebase
--uid
--name
--date
--title
Now I want to get all the ideas generated by a particular uid and attach the query to the recycler. Following is my query and adapter but it returns nothing.
DatabaseReference myIdeasReference = FirebaseDatabase.getInstance().getReference();
final Query myideas =myIdeasReference.child("Ideas")orderByKey().equalTo("userUid",userUid);
mAdapter = new FirebaseRecyclerAdapter<Idea, IdeaHolder>(Idea.class, R.layout.listview_feed, IdeaHolder.class, myideas) {
#Override
public void populateViewHolder(IdeaHolder IdeaViewHolder, final Idea ideaObject, int position) {
int voteCountint = ideaObject.getvoteCount();
String voteCount = Integer.toString(voteCountint);
int flagCountint = ideaObject.getflagCount();
String flagCount = Integer.toString(flagCountint);
String title = ideaObject.gettitle();
String body = ideaObject.getBody();
String postDate = ideaObject.getPostDate();
String mfullName = ideaObject.getfullName();
//pass values :key, Ideauid and Userid to setbutton method in ideaviewholder class
DatabaseReference idearef = getRef(position);//get the database reference of the object at selected position
final String key = idearef.getKey();//get key of the idea reference to get the location later in mvote and mflag
String ideaUid = ideaObject.getuid();
P.S. I also tried the following query:
final Query myideas = myIdeasReference.child("Ideas").orderByValue().equalTo("userUid",userUid);
but then also nothing was displayed.
try with this, this should work for you
myideas = myIdeasReference.child("Ideas").orderByChild("userUid").equalTo(userUid);