Database
From your Dashboard, click the Database button to enter the selected Database.
The look of the UI is similar to Microsoft Excel. The Tables are listed on the left side, as well as the section where you can send Push Notification to all registered users.
The navigation bar shows your Database name and the utility buttons.
The central part of the page is where you see your data.
The Users table gets created when you create a new Database, and it cannot be deleted.
Add a Table
Click the Options button and select Add Table to create a new Table.
Give it a name and click Add table. A new Table will be created and you'll see it on the left-side menu.
Like you did on naming a Database, you must type a Table name with no spaces or special characters!
Import Tables
You can import JSON files as Tables, although their syntax must be compatible with the XServer's syntax, so you may import tables you have previously exported (maybe to make a backup of you data), or Tables provided by an app template you've bought on a marketplace (whic of course is compatible with XServer).
Click the Import Tables button, choose one or more JSON files and let the system load them for you.
Please note that Tables with the same name of the choosen ones will be overwitten.
Export Tables
Click the Export a Table button, choose a Table from the dropdown menu and click the Download Table button. The browser will ask you to save a download.zip
file, accept it. Once it's downloaded, unzip it and get the JSON file of your Table, you can save it in a safe place to make a backup of your data.
Rename a Table
Click the Rename a Table button, select the table you want to rename (please note that the Users
table won't be shown because it cannot be renamed), type a new name and click the Rename Table button.
Again, you must type a Table name with no spaces or special characters!
Delete a Table
Click the Delete Table button, select the table you want to delete (please note that the Users
table won't be shown because it cannot be deleted), and click the Delete Table button.
Add Row
Click the Add Row button, an empty row will be created. You can edit each cell by double-clicking on them and fill the fields.
Edit a Cell
Double-Click on a cell to edit its data. Click the Update button to save it.
Add Column
Click the Add Column button, select the type of your column from the dropdown menu, type your column name (no spaces or special characters allowed), and click the Add Column button.
Please note
When you add a column, XServer adds a custom prefix to its name based on the Type you chose (for instance, if you chose the String type, the prefix will be ST_
).
So, when you are about to configure your mobile or web application, you need to use the full column name, which is made by its prefix, an underscore (_) and its name.
Some examples: ST_myString
, NU_myNumber
, PO_userPointer_Users
, etc...
Column Types
There are 9 types of columns for your data, it's important to know their syntax and meaning, so you'll be able to wisely choose them while creating new columns for your database.
-
ID | composed by
ID_
prefix and id
suffix
This is the object Identifier of each row of the Table. It cannot be created manually, it gets automatically created by the API and its name is always ID_id
-
String | composed by
ST_
prefix | the suffix will be the name you assigned to it.
This is a String to host and display text.
-
Number | composed by
NU_
prefix | the suffix will be the name you assigned to it
It supports integer and decimal numbers. PLEASE NOTE that decimal numbers must have the dot (.) as separator, not the comma (,).
Example: 123.45
-
Array | composed by
AR_
prefix | the suffix will be the name you assigned to it
This type is usually used to store arrays of Strings like object IDs or other text.
It's comma-separated, so be careful while storing an array, put commas where they are needed and do not use the array [""] brackets, just type values separated by commas in the array's input field.
Example: item1,item2,item3
-
File | composed by
FL_
prefix | the suffix will be the name you assigned to it
This type hosts the URL of an uploaded file. Physical files get stored inside the uploads folder
-
Boolean | composed by
BL_
prefix | the suffix will be the name you assigned to it
It's either true or false, as per standard JSON syntax.
Just keep in mind that if you use an input text field instead of a Checkbox or Switch button, the values you must pass are either "0" (True) or "1" (False)
-
GPS | composed by
GPS_
prefix | the suffix will be the name you assigned to it
This type is an array of 2 decimal numbers, the latitude and longitude coordinates, usually used for location purposes.
Like the Number data type, the decimal separator of the coordinates must be a dot (.), and the separator of the 2 coordinates must be a comma (,)
Example: 12.236548,-45.845987
-
Pointer | composed by
PO_
prefix | the suffix will be the name you assigned to it | the Table name where it points to
This type hosts the ID of an object taken from another Table. For instance, a user's ID from the Users table.
If you click it in the Database, it shows the selected object's row
-
Date | composed by
DT_
prefix | the suffix will be the name you assigned to it
The Date format is YYYY-MM-DDTHH:mm:ss
and it's a String
It's important to first plan what tables and columns you need to display and edit in your app or website, then create the necessary Tables and columns in your Database.
Rename Column
Click the Rename Column button, select the column you want to rename from the dropdown menu, type your new column name (no spaces or special characters allowed), and click the Rename Column button.
Delete Column
Click the Delete Column button, select the column you want to delete from the dropdown menu
and click the Delete Column button.
Query
Click the Query button, select a column and a condition from the dropdown menus, type value you want to query and click the Apply Filters button.
Order By
Click the Order By button, select a column and a sorting condition from the dropdown menus, then click the Order Data button.
Order Columns
Click the Order Columns button, reorder the columns by draggingtheir names up or down, then click the Apply button.
iOS SDK
This section covers the foundamentals of the iOS SDK functions to interact with your database on XServer.
Download the SDK from GitHub as a ZIP file.
Download iOS SDK
Installation
Follow these simple steps to integrate the
iOS XServer SDK in your existing Xcoder project:
1. Unzip the downloaded iOS SDK and drag the XServerSDK.swift
and SwiftyJSON.swift
files into your project.
2. Enter the XServerSDK.swift
file and paste your database path in the following variable:
let DATABASE_PATH = "PASTE_YOUR_DATABASDE_PATH"
3. You're ready to go!
Please note that you must not edit the rest of the code in the XServerSDK.swift
file, unless you're an experienced developer, otherwise the SDK will not work properly.
Get Current User XSCurrentUser
You can get the Current User data by calling the XSCurrentUser() function.
Here's an example:
XSCurrentUser { (currentUser) in
if currentUser != nil {
// User is logged in
print(currentUser!["ST_username"].string!)
} else {
// User is logged out...
}
}
Sign In XSSignIn
The Sign In function can be called in a Login screen with a couple of TextFields: username and password.
XSSignIn(username: "myusername", password: "mypassword") { (succ, e) in
if e == nil {
print("Signed in!")
// Do stuff...
// Error
} else { print(e!) }
}
Sign Up XSSignUp
The Sign Up function can be called in a SignUp screen with 3 TextFields: username
, password
and email
.
XSSignUp(username: "myusername", password: "mypassword", email: "myemail", signInWith: "") { (userID, e) in
if e == nil {
var params = ["tableName": "Users"]
params["ID_id"] = userID!
// (Optional) Additional data
// params["ST_fullname"] = "John Doe"
self.XSObject(params) { (succ, e) in
if e == nil {
print("Signed up!")
// Do stuff...
// error
} else { print(e!)
}} // ./ XSObject
// error
} else { print(e!) }
}
As you can see in the code above, you're allowed to register additional data in the Users table by adding extra parameters. Just remember to first add their relative column(s) in the Database. In the example above, we're adding a full name string, which column name is ST_fullname
.
Reset Password XSResetPassword
Users have the ability to also request the app to reset their password, in case they forgot it (or just need to change it).
XSResetPassword(email: "myemail@address.com") { (result, e) in
if e == nil {
print(result!)
} else { print(e!) }
}
The
result
string you'll get will be
"Thanks, an email with a link to reset your password has been sent. Check your Inbox in a little while.".
If you want to change such message, display it like this:
XSResetPassword(email: "myemail@address.com") { (result, e) in
if e == nil {
print("Your new alert message here!")
} else { print(e!) }
}
Logout XSLogout
Users can logout from the app by calling the XSLogout function.
XSLogout { (succ) in
if succ! {
print("Logged out!")
// Do stuff...
} else { print("Something went wrong. Try again.") }
}
Get Pointer object XSGetPointer
In order to retrieve data of a Pointer object use the XSGetPointer
function and pass the object[columnName].string!
and tableName
parameters.
XSGetPointer(myObj["PO_userPointer_Users"].string!, tableName: "Users") { (userPointer) in
print(userPointer!["ST_username"].string!)
}
Refresh object data XSRefreshObjectData
In order to get updated data of an object, call the XSRefreshObjectData
function and pass the tableName
and object
parameters.
XSRefreshObjectData(tableName: "Posts", object: myObj) { (myObj, e) in
if e == nil {
// Do stuff with the updated 'myObj'...
// error
} else { print(e!) }
}
Delete object XSDelete
In order to delete an object, call the XSDelete
function and pass the tableName
and object["ID_id"].string!
parameters.
XSDelete(tableName: "Posts", id: myObj["ID_id"].string!) { (succ, e) in
if e == nil {
print("Object successfully deleted!")
} else { print(e!) }
}
Query objects XSQuery
In order to query objects you have to call the XSQuery
function and pass it the tableName
, columnName
and orderBy
parameters.
Then, inside a for
loop, based on the length of an array of objects, set an if
statement to filter your query by the desired columns and values.
In this example, the query goes by keywords from a UISearchBar:
XSQuery(tableName: "Posts", columnName: "DT_createdAt", orderBy: "") { (objects, e) in
if e == nil {
// For
for i in 0..< objects!.count {
let pObj = objects![i]
// [Search for keywords typed in a UISearchBar]
let keywords = self.searchBar.text!.components(separatedBy: " ")
for j in 0..< keywords.count{
if pObj["ST_text"].string!.lowercased().contains(keywords[j].lowercased())
{ self.objectsArray.append(pObj) }
} // ./ For
// [Finalize array of objects]
if i == objects!.count-1 { self.objectsArray.XSRemoveDuplicatesFromArray() }
} // ./ For
if self.objectsArray.count != 0 {
print(objectsArray)
} else { print("No results!") }
// error on query
} else { print(e!) }
}
Here instead we launch a query based on some filter:
XSQuery(tableName: "Posts", columnName: "DT_createdAt", orderBy: "") { (objects, e) in
if e == nil {
// For
for i in 0..< objects!.count {
let pObj = objects![i]
pObj["ST_category"].string! == "Fun"
|| pObj["NU_likes"].int! == 123
{ self.objectsArray.append(pObj) }
// [Finalize array of objects]
if i == objects!.count-1 { self.objectsArray.XSRemoveDuplicatesFromArray() }
} // ./ For
if self.objectsArray.count != 0 {
print(objectsArray)
} else { print("No results!") }
// error on query
} else { print(e!) }
}
In both the above queries, inside the for
loop, you need to call the XSRemoveDuplicatesFromArray
function to remove duplicates in case your query finds the same objects more than once.
Add/Edit an object XSObject
In order to save an Object you need to call the XSObject
function and pass it the necessary parameters.
var params = ["tableName": "Posts"]
params["ID_id"] = myObj["ID_id"].string! // Used to update an object
params["ST_text"] = "Lorem ipsum dolor sit"
params["NU_number"] = value: "123" // A number must be formatted as a String
params["FL_file"] = "https://example.com/myimage.jpg"
params["DT_date"] = XSGetStringFromDate(myDate) // Used to save a Date()
params["AR_array"] = XSGetStringFromArray(myStringArray) // Used to save an Array[String]
params["GPS_coords"] = XSGetStringFromLocation(myLocation) // used to save a CLLocation()
params["PO_userPointer_Users"] = currentUser["ID_id"].string!
XSObject(params) { (e, obj) in
if e == nil {
print("Object Updated!")
// error
} else { print(e!) }
}
IMPORTANT:
-
In order to update an object, add its ID_id in the parameters array:
params["ID_id"] = myObj["ID_id"].string
-
In order to save a File, make sure to get its URL with the
XSUploadFile
function:
XSUploadFile(fileData: myImageData!, fileName: "image.jpg") { (fileURL, e) in
if e == nil {
print(fileURL!)
var params = ["tableName": "Posts"]
// Add parameter to save the File object
params["FL_file"] = fileURL!
...
// error
} else { print(e!) }
}
-
In order to save a GPS value (CLLocation object with latitude and longitude coordinates), you must convert it into a String with the
XSGetStringFromLocation
function:
params["GPS_coords"] = XSGetStringFromLocation(myLocation)
-
In order to save a Pointer object, you must get its
ID
:
params["PO_userPointer_Users"] = currentUser["ID_id"].string!
-
In order to save an Array value, you must convert it into a String with the
XSGetStringFromArray
function:
var myArray = ["lorem","ipsum","dolor"]
params["AR_array"] = XSGetStringFromArray(myArray)
-
In order to save a Number, either Double or Integer, you must convert it into a String:
params["NU_intNumber"] = "\(123)"
params["NU_doubleNumber"] = "\(12.345)"
-
In order to save a Boolean value, you must convert it into a String and use either 0 or 1:
var myBool = false
var boolStr = ""
if myBool { boolStr = "1" } else { boolStr = "0" } // "0" is True -- "1" is False
params["BL_boolean"] = boolStr
-
In order to save a Date value, you must convert it into a String with the
XSGetStringFromDate
function:
var myDate = Date()
params["DT_date"] = XSGetStringFromDate(myDate)
-
In order to save a String value, just pass it as a String:
params["ST_text"] = "Lorem ipsum dolor sit"
Send a Push Notification XSSendiOSPush
You can send Push Notifications through the app to iOS and Android devices by calling the XSSendiOSPush
and XSSendAndroidPush
functions and passing the message
, deviceToken
and pushType
parameters.
The pushType
parameter can also be empty, like ""
, that's needed just in case you need to pass an extra parameter to your Push Notification, the Push alert will not show that parameter in its message.
// Send iOS Push notification
XSSendiOSPush(message: "Hi there, this is a Push!", deviceToken: userPointer!["ST_iosDeviceToken"].string!, pushType: "chat") { (succ, e) in
if e == nil {
print("iOS PUSH SENT!")
}
}
// Send Android Push notification
XSSendAndroidPush(message: "Hi there, this is a Push!", deviceToken: userPointer!["ST_androidDeviceToken"].string!, pushType: "chat") { (succ, e) in
if e == nil {
print("ANDROID PUSH SENT!")
}
}
In order to be able to send/receive Push Notifications on your device, you must configure it in your Xcode project.
Start by pasting this code into the
didFinishLaunchingWithOptions()
function of the
AppDelegate.swift
file:
let notifTypes:UIUserNotificationType = [.alert, .badge, .sound]
let settings = UIUserNotificationSettings(types: notifTypes, categories: nil)
DispatchQueue.main.async(execute: {
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
application.applicationIconBadgeNumber = 0
})
This will register your device for Push Notifications.
Still inside the
AppDelegate.swift
, add some more delegates:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
IOS_DEVICE_TOKEN = deviceToken.map { String(format: "%02x", $0) }.joined()
print("\nIOS DEVICE TOKEN -> AppDelegate: \(IOS_DEVICE_TOKEN)\n")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("application:didFailToRegisterForRemoteNotificationsWithError: %@", error)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
let notif = JSON(userInfo)
print("Push Body: \(notif["aps"]["alert"]["body"])")
print("Push Type: \(notif["aps"]["alert"]["pushType"])")
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Reset app icon's badge number
application.applicationIconBadgeNumber = 0
}
Android SDK
This section covers the foundamentals of the Android SDK functions to interact with your database on XServer.
Download the SDK from GihHub as a ZIP file.
Download Android SDK
Installation
Follow these simple steps to integrate the Android XServer SDK in your existing Xcoder project:
1. Unzip the downloaded Android SDK, copy the xserver
folder and paste it into the app/src/main/java
folder.
2. Now you have to add a library to allow the SDK to send HTTP requests to the server. Its name is async-http-client-2.1.2.jar
, so copy such file from the libs
folder and paste it into the app/libs
folder of your project.
3. Open the XServerSDK.java
and _FCMService.java
files, expand the import tag and replace
: com.myname.myapp
with your own project's package name (leave .R
at the end of the name), and don't worry for the red errors in the code, they'll get fixed later.
4. Open the build.gradle (Project:YourApp)
file and add this dependency:
classpath 'com.google.gms:google-services:4.3.3'
5. Open the build.gradle (Module:app)
file and add the following repositories and dependencies:
repositories {
google()
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
// Load JAR libraries from the 'libs' folder
implementation fileTree(dir: "libs", include: ["*.jar"])
...
// CircleImageView
implementation 'de.hdodenhof:circleimageview:3.1.0'
// ActionSheet
implementation 'com.github.mkhoiron:Actionsheet-android:0.1'
// JSON parser
implementation 'com.github.amirdew:JSON:v1.0.0'
// Glide (to load images into ImageViews)
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
// DateTime Picker
implementation 'com.github.Kunzisoft:Android-SwitchDateTimePicker:2.0'
// Google & Firebase
implementation 'com.google.android.gms:play-services-auth:18.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'com.google.firebase:firebase-core:17.4.3'
implementation 'com.google.firebase:firebase-messaging:20.2.1'
}
apply plugin: 'com.google.gms.google-services'
After that, you may need to Sync your project, so click the
Sync Now link and wait for Gradle to sync:
6. Since you've added apply plugin: 'com.google.gms.google-services'
, which is needed for Firebase Push Notifications, you have to download the google-services.json
file from your Firebase Project settings and copy it into the app
folder of your project.

In case you don't use Firebase FCM in your app, you may remove this line: apply plugin: 'com.google.gms.google-services'
. Also, don't download the google-services.json
and don't put it into the app
folder.
7. Open the Manifest.xml
file and paste the following permissions:
<!-- Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.CAMERA" />
<!-- Push Notifications -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
8. Then paste this code inside the <application>
tag:
android:usesCleartextTraffic="true"
android:requestLegacyExternalStorage="true"
tools:ignore="AllowBackup,GoogleAppIndexingWarning,UnusedAttribute"
9. If you use Firebase FCM in your app, add this piece of code before the <application>
closure:
<!-- FCM Service -->
<service
android:name="xserver.app._FCMService"
android:stopWithTask="false"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
10. Open the XServerSDK.java
file and paste your own database path, then you'll be ready to go:
public static String DATABASE_PATH = "YOUR_DATABASE_PATH";
11. You're ready to go!
Please note that you must not edit the rest of the code in the XServerSDK.java
file, unless you're an experienced developer, otherwise the SDK will not work properly.
Current User XSCurrentUser
You can get the Current User data by calling the
XSCurrentUser()
function.
XSCurrentUser(this, new XSCurrentUserHandler() { @Override public void done(final JSON currentUser) {
if (currentUser != null) {
// Do stuff with currentUser
} else {
Log.i("xs", "Current User is not logged in");
}
}});
Sign In XSSignIn
The Sign In function can be called in a Login screen with a couple of EditText widgets: username and password.
XSSignIn((Activity)ctx, "myusername", "mypassword", new XSSignInHandler() {
@Override
public void done(boolean success, String e) {
if (e == null) {
Log.i("xs", "Signed in!");
// error
} else { Log.i("xs", e); }
}});
Sign Up XSSignUP
The Sign Up function can be called in a SignUp screen with 4 EditText widgets: username, password, email and fullname (this last one is optional, but we'll keep it for this example).
XSSignUp((Activity) ctx, "myusename", "mypassword", "myemail", "", new XSSignUpHandler() {
@Override public void done(String result, String e) {
if (e == null) {
RequestParams params = new RequestParams();
params.put("tableName", "Users"); // <- Mandatory
params.put("ID_id", result); // <- Mandatory
// Additional data (full name)
params.put("ST_fullname", fullnameTxt.getText().toString());
XSObject((Activity)ctx, params, new XSObjectHandler() { @Override public void done(boolean success, String e) {
if (e == null) {
Log.i("xs", "Signed up!");
// error
} else { Log.i("xs", e);
}}});
// error
} else { Log.i("xs", e); }
}});
As you may notice from the code above, it calls 2 functions: the
XSSignUp
one to store the default User's data, such as username, password and email, then the
XSObject
function. This updates the new User with additional data - in this case, it's the fullname string.
So, in case you have additional data to store in the Users table while signing up, you must add them as parameteres inside the
XSSignUp
function, as shown above, keeping in mind the the "tableName" and the "ID_id" parameters must be included.
Reset Password XSResetPassword
Users have the ability to also request the app to reset their password, in case they forgot it (or just need to change it).
XSResetPassword((Activity)ctx, "myemail@address.com", new ResetPasswordHandler() {
@Override
public void done(String result, String error) {
if (error == null) {
Log.i("xs", result);
} else {
Log.i("xs", error);
}
}});
The result string you'll get will be
"Thanks, an email with a link to reset your password has been sent. Check your Inbox in a little while.".
If you want to change such message, just set your own message string:
XSResetPassword((Activity)ctx, "myemail@address.com", new ResetPasswordHandler() {
@Override
public void done(String result, String error) {
if (error == null) {
Log.i("xs", "My new message here");
}
}});
Logout XSLogout
Users can logout from the app by calling the
XSLogout
function.
XSLogout(new LogoutHandler() { @Override public void done(boolean success) {
if (success) {
Log.i("xs", "Logged out!");
} else {
Log.i("xs", Something went wrong. Try again");
}
}});
Get Pointer object XSGetPointer
If you've set a column of type
Pointer in your Database and you need to retrieve the data of its object, use the
XSGetPointer
function and pass the
object.key(columnName).stringValue()
and
tableName
parameters.
XSGetPointer((Activity) ctx, myObj.key("PO_userPointer_Users").stringValue(), "Users", new XSPointerHandler() {
@SuppressLint("SetTextI18n")
@Override
public void done(final JSON userPointer, final String e) {
if (e == null) {
// Do stuff with this 'userPointer' object
// error
} else { log.i("xs", e);
}}});
Refresh object data XSRefreshObjectData
In order to get updated data of an object, call the
XSRefreshObjectData
function and pass the
tableName
and
Object
parameters.
XSRefreshObjectData((Activity)ctx, "Posts", myObj, new XSRefreshObjectDataHandler() {
@Override
public void done(JSON myObj, String error) {
if (error == null){
// Use 'myObj' as you wish...
// error
} else { hideHUD(); simpleAlert(error, ctx); }
}});
Delete an object XSDelete
You can delete an object by calling the
XSDelete
function and passing the
tableName
and
object.key("ID_id").stringValue()
parameters.
XSDelete((Activity)ctx, "Posts", pObj.key("ID_id").stringValue(), new XSDeleteHandler() {
@Override
public void done(boolean success, String e) {
if (e == null) {
Log.i("xs", "Object successfully deleted!");
// error
} else { Log.i("xs", e);
}}});
Query objects XSQuery
You can query objects by calling the
XSQuery
function and passing it the
tableName
,
columnName
and
orderBy
(optional) parameters.
Then, inside a
for
loop based on the length of an array of JSON objects, set an
if
statement to filter your query by the desired columns and values.
In this example, the query goes by keywords from an EditText:
XSQuery((Activity)ctx, "Posts", "DT_createdAt", "descending", new XSQueryHandler() {
@Override public void done(JSON objects, String error) {
if (error == null) {
for (int i = 0; i < objects.count(); i++) {
JSON pObj = objects.index(i);
// [Search for keywords typed in an EditText]
String[] keywords = myEditText.toLowerCase().split(" ");
if (searchText.length() != 0) {
for (String keyword : keywords) {
objectsArray.add(pObj);
}
}
// [Finalize array of objects]
if (i == objects.count()-1) { objectsArray = XSRemoveDuplicatesFromArray(objectsArray); }
}// ./ For
if (objectsArray.size() != 0) {
Log.i("xs", objectsArray);
// No results
} else { Log.i("xs", "No results!"); }
// error
} else { Log.i("xs", error); }
}});
Here instead we launch a query based on some filter:
XSQuery((Activity)ctx, "Posts", "DT_createdAt", "", new XSQueryHandler() {
@Override public void done(JSON objects, String error) {
if (error == null) {
for (int i = 0; i < objects.count(); i++) {
JSON pObj = objects.index(i);
if (
pObj.key("ST_category").stringValue().matches("Fun")
|| pObj.key("NU_likes").intValue() == 789789
){ objectsArray.add(pObj); }
// [Finalize array of objects]
if (i == objects.count()-1) { objectsArray = XSRemoveDuplicatesFromArray(objectsArray); }
}// ./ For
if (objectsArray.size() != 0) {
Log.i("xs", objectsArray);
// No results
} else { Log.i("xs", "No results!"); }
// error
} else { Log.i("xs", error); }
}});
In both the above queries, inside the for
loop, you need to call the XSRemoveDuplicatesFromArray
function to remove duplicates in case your query finds the same objects more than once.
Add/Edit an object XSObject
In order to save a new Object you need to call the
XSObject
function and pass it the necessary parameters.
// Parameters
RequestParams params = new RequestParams();
params.put("tableName", "Posts");
params.put("ID_id", myObj.key("ID_id").stringValue()); // Used to update an object | remove this line if you're saving a NEW object!
params.put("ST_text", "Lorem ipsum dolor sit");
params.put("NU_number", "123.45"); // A number must be formatted as a String
params.put("FL_file", "https://example.com/myimage.jpg");
params.put("DT_date", XSGetStringFromDate(selectedDate)); // Used to save a Date()
params.put("AR_array", XSGetStringFromArray(myArray)); // Used to save a ListArray()
params.put("GPS_coords", XSGetStringFromLocation(myLocation));// Used to save a Location()
params.put("PO_userPointer_Users", currentUser.key("ID_id").stringValue());
XSObject((Activity)ctx, params, new XSObjectHandler() { @Override public void done(String e, JSON obj) {
if (e == null) {
Log.i("xs", "Object saved!");
// error
} else { Log.i("xs", e);
}}});
IMPORTANT:
In order to UPDATE an object, add its
ID
in the parameters array.
params.put("ID_id", myObj.key("ID_id").stringValue());
In order to save a
File, make sure to get its URL with the
XSUploadFile
function.
XSUploadFile(filePath,"image.jpg", (Activity)ctx, new XSFileHandler() {
@Override public void done(String fileURL, String e) {
if (fileURL != null) {
// Add parameter to save the File object
params.put("FL_file", fileURL);
...
// Upload failed
} else { Log.i("xs", e); }
}});
In order to save a
GPS
value (Location with latitude and longitude coordinates), you must use the
XSGetStringFromLocation()
function to convert the Location object into a String.
params.put("GPS_coords", XSGetStringFromLocation(myLocation));
In order to save a
Pointer object, you must get its
ID
.
params.put("PO_userPointer_Users", currentUser.key("ID_id").stringValue());
In order to save an
Array value, you must convert it into a String with the
XSGetStringFromArray
function.
List<String> myArray = new ArrayList<>();
myArray.add("asD4e5Fo9");
params.put("AR_array", XSGetStringFromArray(myArray));
In order to save a
Number, you must convert it into a String.
params.put("NU_number", String.valueOf(1234));
// OR
params.put("NU_number", String.valueOf(45.678));
In order to save a
Boolean
value, you must convert it into a String and set it either as "0" or "1".
String bool = "1"; // "0" is False, "1" is True
params.put("BL_bool", bool);
In order to save a
Date value, you must convert it into a String with the
XSGetStringFromDate
function.
Date date = new Date();
params.put("DT_date", XSGetStringFromDate(date));
In order to save a
String value, just pass it as a String.
params.put("ST_text", "Lorem ipsum dolor sit");
Send a Push Notification
You can send Push Notifications through the app to iOS and Android devices by calling the
XSSendiOSPush
and
XSSendAndroidPush
functions and passing the
message
,
deviceToken
and
pushType
parameters.
The
pushType
value can also be empty, like "", that's needed just in case you need to pass an extra parameter to your Push Notification.
// Send Android Push Notification
XSSendAndroidPush((Activity)ctx, pushMessage, userPointer.key("ST_androidDeviceToken").stringValue(), "chat", new XSAndroidPushHandler() {
@Override
public void done(boolean success, String e) {
if (e == null) {
Log.i("xs", "ANDROID PUSH SENT!");
// error
} else { Log.i("xs", e); }
}});
// Send iOS Push Notification
XSSendiOSPush((Activity)ctx, pushMessage, userPointer.key("ST_iosDeviceToken").stringValue(), "chat", new XSiOSPushHandler() {
@Override
public void done(boolean success, String e) {
if (e == null) {
Log.i("xs", "iOS PUSH SENT");
// error
} else { Log.i("xs", e); }
}});
Web SDK
This section covers the foundamentals of the Web SDK functions to interact with your database on XServer.
Download Web SDK
The SDK code is mainly written in Javascript, with the aid of jQuery, so you would need to use the $('#yourDivID').append()
function to display data in your website.
Installation
Follow these simple steps to integrate the Android XServer SDK in your existing Xcoder project:
1. Unzip the downloaded Web SDK, then upload the js
folder and the XServerSDK.php
file in the root of your website (usually the public_html
directory.
If you already have a
js
folder in the root of your server, then just upload the
jquery-3.4.1.min.js
and
swal2.js
files inside your
js
folder, so you will not overwrite your existing files.
2. In the index.php
file of your website, make sure to import those 2 files inside the <head>
tag:
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/swal2.js"></script>
3. You're ready to go.
Current User XSCurrentUser
You can get the Current logged in User by calling the
XSCurrentUser
function.
<script>
var currentUser = XSCurrentUser();
if (currentUser != null) {
console.log(currentUser['ID_id']);
} else {
console.log('currentUser is not logged in...');
}
</script>
Sign In XSSignIn
To sign in as an existing user you have to call the
XSSignIn()
function and pass the
usename
and
password
parameters, usually via HTML inputs with the
id and
name tags set as
'username'
and
'password'
.
The Sign in button gets called by a JQuery function like this:
$(function () { $("#loginButton").click(function () ... });
.
<!-- Sing in form -->
<input id="username" name="username" type="text" placeholder="Username">
<input id="password" name="password" type="password" placeholder="Password">
<!-- Sign In Button -->
<button id="loginButton" name="loginButton">Sign In</button>
<script>
$(function () { $("#loginButton").click(function () {
XSSignIn();
});
});
</script>
Sign Up XSSignUp
To sign up as a new user you have to call the
XSSignUp()
function and pass
usename
,
password
and
email
parameters, usually via HTML inputs with id and name tags set as 'usename', 'password', 'email'.
For additional parameters - for example, fullname, file, etc. - you must add them into the
XSSignUp()
function in the
XServerSDK.php
file, like this example:
var p2 = { 'tableName': 'Users' };
p2['ID_id'] = cuArr[0];
// Additional data (optional)
p2['BL_bool'] = '0';
p2['ST_fullname'] = $('#fullName').val();
p2['FL_file'] = 'https://xserver.app/assets/img/default_avatar.png';
XSObject(p2);
As you can see by the code above, the function's parameters needs to get the Users table, the ID
of the signed up User and then the additional data (the extra columns you may have added to the Users table).
The Sign up button gets called by the JQuery function: $(function () { $("#signUpButton").click(function () { ... });
<!-- Inputs to pass data -->
<input id="username" name="username" type="text">
<input id="password" name="password" type="password">
<input id="email" name="email" type="email">
<!-- Additional data -->
<input id="fullName" name="fullName" type="text">
<!-- Sign up button -->
<button id="signUpButton">Sign Up</button>
<script>
// Sign Up
$(function () { $("#signUpButton").click(function () {
if ($('#username').val() == ''
|| $('#password').val() == ''
|| $('#email').val() == ''
|| $('#fullName').val() == ''
){ console.log('Please fill all the fields.');
} else {
var params = { 'signInWith': '' };
params['ST_username'] = $('#username').val();
params['ST_password'] = $('#password').val();
params['ST_email'] = $('#email').val();
params['ST_iosDeviceToken'] = '';
params['ST_androidDeviceToken'] = '';
XSSignUp(params);
}// ./ If
});
});
Reset Password XSResetPassword
The
XSResetPassword()
function fires an alert by SweetAlert with a text input where you have to type your valid email address and click the
Reset Password button.
Here's how you call that function:
<a class="btn btn-warning" href="#" onclick="XSResetPassword()">Reset password</a>
Check the
XSResetPassword()
function in the
XServerSDK.php
file to edit the alert messages as you wish.
Query objects XSQuery
You can query objects by calling the
XSQuery
function and passing it the
tableName
,
columnName
and
orderBy
parameters.
Then, inside a
for
loop based on the length of an array of JSON objects, set an
if
statement to filter your query by the desired keys (columns) and values.
<script>
function queryObjects() {
var objects = XSQuery(
'tableName=' + 'Posts' // Set the Table name
+ '&columnName=' + 'DT_createdAt' // Get the createdAt Date column
+ '&orderBy=' + 'descending' // OR 'ascending'
);
// array of objects
var objectsArray = [];
for (var i = 0; i < objects.length; i++) {
// JSON Obj
var obj = objects[i];
// Query filters
if(
obj['ST_category'] == 'Fun'
|| obj['NU_likes'] == 1234
){ objectsArray.push(obj); }
// Finalize array of objects by removing duplicates (if any)
if (i == objects.length-1) {
objectsArray = XSRemoveDuplicatesFromArray(objectsArray);
showData(objectsArray);
}
}// ./ For
}
// Show Data
function showData(objectsArray) {
for(var i = 0; i < objectsArray.length; i++){
// JSON object
var obj = objectsArray[i];
console.log(obj['ID_id']);
...
}
}
</script>
Refresh object data XSRefreshObjectData
In order to get updated data of an object, call the
XSRefreshObjectData
function and pass the
tableName
and the
object's ID
parameters.
<script>
var refreshedObject = XSRefreshObjectData("Users", "as34FiPrT");
console.log(refreshedObject['ST_username']);
...
</script>
Get Pointer object XSGetPointer
You can get the object's data of a Pointer object by calling the
XSGetPointer()
function and passing it the
columnName
and
tableName
parameters.
<script>
var userPointer = XSGetPointer(obj['PO_userPointer_Users'], 'Users');
console.log(userPointer['ST_username']);
</script>
Add/Edit an object XSObject
In order to save an Object you need to call the
XSObject()
function and pass it the necessary parameters, usually via HTML inputs with the
id and
name tags set as the column names that need to be saved.
<textarea type="text" id="ST_text" name="ST_text" rows="2" ></textarea>
<input type="number" step="any" id="NU_likes" name="NU_likes" value="0">
...
<!-- Save Object button -->
<a href="#" id="saveButton" class="btn btn-info btn-block">Save Object</a>
<script>
$(function () {
// Save object [XSObject]
$("#saveButton").click(function () {
// Prepare data
var params = {'tableName=':'Posts'};
params['ID_id'] = 'asSe45Fru'; // USE THIS TO UPDATE AN OBJECT - REMOVE THIS LINE TO SAVE A NEW OBJECT
params['ST_text'] = $('#ST_text').val();
params['NU_likes'] = $('#NU_likes').val();
// Save
var result = XSObject(params);
if (result.includes('ID_id')) {
console.log('Object successfully saved/updated');
}
});
</script>
Delete an object XSDelete
In order to delete an object you need to call the
XSDelete()
function and pass the
tableName
and
id
parameters.
<script>
var params =
'tableName=' + 'Posts' +
'&id=' + 'nh6Ft8Lit'
;
var result = XSDelete(params);
if (result == 'deleted') {
console.log('Object successfully deleted!');
}
</script>
Send Push Notifications XSSendPushNotification
In order to send Push Notifications to iOS and Android devices, call the
XSSendPushNotification()
function and pass the
tokentString
(made by the iOS Token + the Android token), the
message
and the
piuhType
parameters.
<script>
var pushMessage = 'Hi there, this is a Push message!';
var tokensStr = receiverUser['ST_iosDeviceToken'] + ',' + receiverUser['ST_androidDeviceToken'];
XSSendPushNotification(tokensStr, pushMessage, 'chat');
</script>
Unity SDK
This section covers the foundamentals of the Unity SDK functions to interact with your database on XServer.
Download the SDK from GitHub as a ZIP file.
Download Unity SDK
Installation
Follow these simple steps to integrate the Unity XServer SDK in your existing Unity project:
1. Unzip the downloaded Unity SDK, drag the XServerSDK
folder into Assets folder.
2. Open the XServerSDK.cs
file, paste your own database path and save the file, then you'll be ready to go:
public static String DATABASE_PATH = "YOUR_DATABASE_PATH";
3. You're ready to go, just remember to import the following references on the top of each Script file you'll create in order to use the SDK:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using UnityEditor;
using System;
using System.Net;
using System.Text;
using System.IO;
using UnityEngine.SceneManagement;
using SimpleJSON;
Please note that you must not edit the rest of the code in the XServerSDK.cs
file, unless you're an experienced developer, otherwise the SDK will not work properly.
Current User XSCurrentUser
You can get the Current User data by calling the
XSCurrentUser()
function.
JSONNode currentUser = XServerSDK.XSCurrentUser();
if(currentUser != null) {
// Do stuff with currentUser
} else { Debug.Log("currentUser is logged out"); }
Sign In XSSignIn
The Sign In function can be called in a Login scene with a couple of InputField UI components: username and password.
if (usernameField.text == "" || passwordField.text == ""){
XServerSDK.simpleAlert("Please type a username and a password.");
} else {
var result = XServerSDK.XSSignIn(usernameField.text, passwordField.text);
if(result) { SceneManager.LoadScene("MainScene"); }
}
Sign Up XSSignUP
The Sign Up function can be called in a SignUp screen with 4 InputField components: username, password, email and fullname (this last one is optional, but we'll keep it for this example).
if (usernameField.text == "" || passwordField.text == "" || emailField.text == "" || fullnameField.text == ""){
XServerSDK.simpleAlert("Please insert username, password, email and full name.");
} else {
var signUpResult = XServerSDK.XSSignUp("unityUser", "qqq", "unity@mail.com", "");
// Additional user's data
List<String> parameters = new List<String>();
parameters.Add(XServerSDK.param("tableName", "Users"));
parameters.Add(XServerSDK.param("ID_id", signUpResult));
parameters.Add(XServerSDK.param("ST_fullname", "Unity Gamer"));
parameters.Add(XServerSDK.param("BL_bool", "0"));
parameters.Add(XServerSDK.param("FL_aFile", "0"));
var result = XServerSDK.XSObject(parameters);
if (result.ToString().Contains("ID_id")){
Debug.Log("NEW USER SIGNED UP: " + result.ToString());
SceneManager.LoadScene("Home");
}
}
As you may notice from the code above, it calls 2 functions: the
XSSignUp
one to store the default User's data, such as username, password and email, then the
XSObject
function. This updates the new User with additional data - in this case, it's the fullname string.
So, in case you have additional data to store in the Users table while signing up, you must add them as parameteres inside the
XSSignUp
function, as shown above, keeping in mind the the "tableName" and the "ID_id" parameters must be included.
Reset Password XSResetPassword
Users have the ability to also request the app to reset their password, in case they forgot it (or just need to change it).
var result = XServerSDK.XSResetPassword("my@email.com");
if(result != null){ XServerSDK.simpleAlert(result); }
The result string you'll get will be
"Thanks, an email with a link to reset your password has been sent. Check your Inbox in a little while.".
If you want to change such message, just set your own message string in this line:
if(result != null){ XServerSDK.simpleAlert("My new messsae here."); }
Logout XSLogout
Users can logout from the app by calling the
XSLogout
function.
if (EditorUtility.DisplayDialog(XServerSDK.GAME_NAME, "Are you sure you want to logout?", "Logout", "Cancel")){
// Logout
if(XServerSDK.XSLogout()) { Debug.Log("Logged out!"); }
}
Get Pointer object XSGetPointer
If you've set a column of type
Pointer in your Database and you need to retrieve the data of its object, use the
XSGetPointer
function and pass the
object[columnName]
and
tableName
parameters.
var userPointer = XServerSDK.XSGetPointer("Users", obj["PO_userPointer_Users"]);
// Do stuff with this 'userPointer' object
Refresh object data XSRefreshObjectData
In order to get updated data of an object, call the
XSRefreshObjectData
function and pass the
tableName
and
Object
parameters.
var refreshedObj = XServerSDK.XSRefreshObjectData("Posts", myObject);
Debug.Log("refreshed Object: " + refreshedObj.ToString());
Delete an object XSDelete
You can delete an object by calling the
XSDelete
function and passing the
tableName
and
object["ID_id"]
parameters.
var result = XServerSDK.XSDelete("Posts", "Abc123Def");
if(result) { Debug.Log("Object deleted!"); }
Query objects XSQuery
You can query objects by calling the
XSQuery
function and passing it the
tableName
,
columnName
and
orderBy
(optional) parameters.
Then, inside a
for
loop based on the length of an array of JSON objects, set an
if
statement to filter your query by the desired columns and values.
List<JSONNode> objectsArray = new List<JSONNode>();
var objects = XServerSDK.XSQuery("Posts", "DT_createdAt", "");
for(int i=0; i<objects.Count; i++){
var obj = objects[i];
// [Query Filters]
if (obj["NU_likes"] == 123
|| obj["ST_category"] == "Game"
|| obj["AR_likedBy"].ToString().Contains("item1")
){ objectsArray.Add(obj); }
} //./ for
// Show data
if (objectsArray.Count != 0){
for (int i = 0; i < objectsArray.Count; i++){
var obj = objectsArray[i];
Debug.Log(obj["ST_text"]);
Debug.Log(obj["BL_aBool"]);
var date = XServerSDK.XSGetDateFromString(obj["DT_myDate"]);
Debug.Log(date.ToString("MMM dd, yyyy"));
// Get image from URL
StartCoroutine(XServerSDK.GetImageFromURL(obj["FL_aFile"], myImage));
} //./ For
// No results
} else { Debug.Log("No results!"); }
Add/Edit an object XSObject
In order to save a new Object you need to call the
XSObject
function and pass it the necessary parameters.
// Parameters
List parameters = new List();
parameters.Add(XServerSDK.param("tableName", "Posts"));
parameters.Add(XServerSDK.param("ST_text", "Text from Unity Game!"));
parameters.Add(XServerSDK.param("AR_likedBy", XServerSDK.XSGetStringFromArray(myArray))); // Save a List()
parameters.Add(XServerSDK.param("NU_likes", 12.34.ToString())); // Save a Number
parameters.Add(XServerSDK.param("GPS_coords", 12.3456789.ToString() + "," + -14.654987.ToString())); // Save a GPS Location
parameters.Add(XServerSDK.param("DT_aDate", XServerSDK.XSGetStringFromDate(myDate))); // Used to save DateTime
parameters.Add(XServerSDK.param("BL_aBool", "1")); // "0" -> FALSE | "1" -> TRUE
parameters.Add(XServerSDK.param("FL_aFile", fileURL));
// Save
var result = XServerSDK.XSObject(parameters);
if (result.ToString().Contains("ID_id")){
Debug.Log("OBJECT SAVED/UPDATED: " + result.ToString());
}
IMPORTANT:
In order to UPDATE an object, add its
ID
in the parameters array.
parameters.Add(XServerSDK.param("ID_id", myObj["ID_id"]));
In order to save a
File, make sure to get its URL with the
XSUploadFile
function.
// Get bytes[] of file
byte[] bytes = File.ReadAllBytes(Application.dataPath + "/Res/image.jpg");
// Upload a file
StartCoroutine(XServerSDK.XSUploadFile(bytes, "image.jpg", fileURL => {
Debug.Log("UPLOADED FILE URL: " + fileURL);
parameters.Add(XServerSDK.param("FL_file", fileURL));
...
}})); //./ XSUploadFile
In order to save a
GPS
value (Location with latitude and longitude coordinates), you must convert coordinates into a String.
parameters.Add(XServerSDK.param("GPS_coords", 12.123456.ToString() + "," + -14.654987.ToString()));
In order to save a
Pointer object, you must get its
ID
.
parameters.Add(XServerSDK.param("PO_userPointer_Users", currentUser["ID_id"]));
In order to save an
Array value, you must convert it into a String with the
XSGetStringFromArray
function.
List<String> myArray = new ArrayList<>();
myArray.add("asD4e5Fo9");
parameters.Add(XServerSDK.param("AR_array", XServerSDK.XSGetStringFromArray(myArray)));
In order to save a
Number, you must convert it into a String.
parameters.Add(XServerSDK.param("NU_number", 1234.ToString()));
In order to save a
Boolean
value, you must convert it into a String and set it either as "0" or "1".
String bool = "1"; // "0" is False, "1" is True
parameters.Add(XServerSDK.param("BL_bool", bool));
In order to save a
Date value, you must convert it into a String with the
XSGetStringFromDate
function.
var myDate = System.DateTime.Now;
parameters.Add(XServerSDK.param("DT_aDate", XServerSDK.XSGetStringFromDate(myDate)));
In order to save a
String value, just pass it as a String.
parameters.Add(XServerSDK.param("ST_text", "Lorem ipsum dolor sit amet"));
Send a Push Notification
You can send Push Notifications through the game to iOS and Android devices by calling the
XSSendiOSPush
and
XSSendAndroidPush
functions and passing the
message
,
deviceToken
and
pushType
parameters.
The
pushType
value can also be empty, like "", that's needed just in case you need to pass an extra parameter to your Push Notification.
var iosPush = XServerSDK.XSSendiOSPush("Push from Unity!", userObj["ST_ioDeviceToken"], "chat");
var anPush = XServerSDK.XSSendAndroidPush("Push from Unity!", userObj["ST_androidDeviceToken"], "chat");