How to use firebase with laravel resource? - laravel

I have an API endpoint to return all the messages. I am using resources for that. From my local database I can do that very conveniently. Now I have switched to firebase for realtime connection. So my resource is not working. can anyone help me out in this scenario?
Resource code:
return [
'text' => $this->message,
'created_at' => $this->created_at->setTimezone('Asia/Kuala_Lumpur')->format('Y-m-d H:i:s'),
'status' => $this->status,
'replied_by' => $replied_by,
'author' => $this->findAuthorInfo()
];
Controller code:
$firestore = app('firebase.firestore');
$database = $firestore->database();
$c = $database->collection('collection')->where('user_id', '=', Auth::guard('api')->user()->id);
return [
'success' => true,
'message' => 'Messages',
'data' => UserMessageResource::collection($c)
];

Related

undefined index data laravel

i'm integrating this login api on laravel:
endpoint: http://127.0.0.1:8888/api/v1/users/login/
parameter:
{"data":{
"email":"admin#mail.com",
"password":"admin#123",
"user_type":"1",
"encrypted":false
},"encoded_data":"yes"}
controller:
i'm posting data from form:
$request->validate([
'username' => 'required',
'password' => 'required',
'user_type' => 'required'
]);
$ds = $request->all();
$url = $this->base_api_url . 'api/v1/users/login/';
$apiRequest = [
'data' => [
'email' => $ds['username'],
'password' => $ds['password'],
'user_type' => $ds['admin'],
'encrypted' => false
],
'encoded_data' => 'yes',
];
$apiResponse = Http::acceptJson()->post($url, $apiRequest);
dd($apiResponse);
its return:
{"error":1,"success":false,"message":"Undefined index: data"}
this is the parameter i'm sending in $apiRequest:
array:2 [▼
"data" => array:4 [▼
"email" => "admin#mail.com"
"password" => "admin#123"
"user_type" => "1"
"encrypted" => false
]
"encoded_data" => "yes"
]
api working fine on postman:
I think you are requesting json format data so you need to get with by using this$request->json()->all() by using this you can access the key value.
Laravel Http::post sends a normal post request (form data). You should also send the Content-type: application/json header so the Laravel API understands it.
Try using the following:
$apiResponse = Http::accept('application/json')->post($url, $apiRequest);
// or
$apiResponse = Http::acceptJson()->post($url, $apiRequest);

Laravel Phpunit testing a request that take give output based on the request

I'm still new to laravel and I have a simple app and aSo I have a route that will store data based on the request in my controller.
public funtion store(Request $request, $id){
if ($request->has('work_experiences')) {
WorkExperience::create([
'user_id' => $user->id,
'position' => $request->work_experiences['position'],
'company' => $request->work_experiences['company'],
'start_date' => $request->work_experiences['start_date'],
'end_date' => $request->work_experiences['end_date'],
]);
}
if ($request->has('education')) {
Education::create([
'user_id' => $user->id,
'degree' => $request->education['degree'],
'university' => $request->education['university'],
'start_date' => $request->education['start_date'],
'end_date' => $request->education['end_date'],
]);
}
if ($request->has('job_interests')) {
JobInterest::create([
'user_id' => $user->id,
'job_position' => $request->job_interests['position'],
]);
}}
}
and in my test
public function test_authenticated_user_can_edit_education_profile()
{
$this->withoutExceptionHandling();
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/candidate' . '/' . $user->id, [
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
]);
$this->assertCount(1, WorkExperience::all());
}
when I run the test, the assertCount seems to fail because the response didn't work/insert the data to DB. where do I do wrong?
Well, the test is right.
It should fail because there is no work_experiences key in your request data.
The test request should look like:
$response = $this->post('/candidate' . '/' . $user->id, [
'work_experiences' => [
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
]
]);
So your data should go under a work_experiences key such that $request->has('work_experiences') returns true and executes the WorkExperience::create() statement.
Currently your endpoint only allows for a single "work experience" to be created. Seeing that you've named it work_experiences I assume you'd want to pass in an array/collection of "work experiences" - but that won't work with the current implementation; you'll have to loop over them instead - something like this:
if ($request->has('work_experiences')) {
foreach ($request->input('work_experiences') as $experience) {
WorkExperience::create([
'user_id' => $request->user()->id,
'position' => $experience['position'],
'company' => $experience['company'],
'start_date' => $experience['start_date'],
'end_date' => $experience['end_date'],
]);
}
}
And then your test should look something like this:
$response = $this->post('/candidate' . '/' . $user->id, [
'work_experiences' => [
[
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
],
// more "work experiences"
]
]);

Laravel: Add custom data to resource

First I get the translator by his id using this line of code
$translator = Translator::where('id', $translator_id)->first();
Then I send a notification to him by this code:
$response = Http::withHeaders([
'Authorization' => 'key=myKey',
'Content-Type' => 'application/json'
])->post('https://fcm.googleapis.com/fcm/send', [
"notification" => [
"title" => "title",
"body" => "body",
],
"data" => [
"title" => "title",
"body" => "body",
],
"to" => $token,
]);
Everything works fine but my problem is that when I return the TranslatorResource I want to add the notification response to it, so I do this in my controller
$resource = new TranslatorResource($translator);
$resource->notif = $response;
return $resource;
And in TranslatorResource I have this code:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'phone' => $this->phone,
'cv' => $this->cv,
'specialization' => $this->specialization,
'tr_languages' => $this->tr_languages,
'all_languages' => $this->all_languages,
'isVerified' => $this->isVerified == 0 ? false : true,
'isActive' => $this->isActive == 0 ? false : true,
'completed_orders' => $this->completed_orders,
'canceled_orders' => $this->canceled_orders,
'rejected_orders' => $this->rejected_orders,
'current_orders' => $this->current_orders,
'isTranslator' => true,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
But I only get the data specified in the resource, the notif key isn't added, anyone know how to add this data to my resource when I return it ?
You can use additional method provided by laravel.
return (new TranslatorResource($translator))->additional(['notif ' => $response]);
Reference: Eloquent: API Resources
You can look for the section Adding Meta Data When Constructing Resources.

laravel client api with guzzle

I'm using API from RapidAPI face verification https://rapidapi.com/HiBrainy/api/face-recognition4 and
I have difficulty using the API
this example code PHP from RapidAPI
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->addForm(array(
'photo1' => array(
'value' => 'image2.jpg',
'data' => 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAQ=='
),
'photo2' => array(
'value' => 'image2.jpg',
'data' => 'data:image/jpeg;base64,/9j/4AAQSkZ630QAMXaf//Z'
)
), NULL);
$request->setRequestUrl('https://face-recognition4.p.rapidapi.com/FaceVerification');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'x-rapidapi-host' => 'face-recognition4.p.rapidapi.com',
'x-rapidapi-key' => $my_api_key,
'content-type' => 'multipart/form-data'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
I applied to laravel with the guzzle package
my code
try {
...other code...
$client = new Client();
$response = $client->post('https://face-recognition4.p.rapidapi.com/FaceVerification', [
'headers' => [
'x-rapidapi-host' => 'face-recognition4.p.rapidapi.com',
'x-rapidapi-key' => $my_api_key,
'content-type' => 'multipart/form-data'
],
'multipart' => [
[
'name' => 'photo1',
'contents' => $image1,
'filename' => 'image1.jpg'
],
[
'name' => 'photo2',
'contents' => $image2,
'filename' => 'image2.jpg'
]
]
]);
}catch (\Exception $error){
dd($error);
}
I got error
#message: """
Client error: `POST https://face-recognition4.p.rapidapi.com/FaceVerification` resulted in a `400 Bad Request` response:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":4 (truncated...)
You should consider removing your API key from the code you're sharing
Try to have a look at the raw request to have further details and verify that your request have been formatted correctly

Post Multipart and Json together with Guzzle in Laravel

I'm trying to POST multipart and json data with Guzzle to build my apps with Phonegap Build API. I've tried many adjustment but still got error results. Here's the latest function I'm using:
public function testBuild(Request $request)
{
$zip_path = storage_path('zip/testing.zip');
$upload = $this->client->request('POST', 'apps',
['json' =>
['data' => array(
'title' => $request->title,
'create_method' => 'file',
'share' => 'true',
'private' => 'false',
)],
'multipart' =>
['name' => 'file',
'contents' => fopen($zip_path, 'r')
]
]);
$result = $upload->getBody();
return $result;
}
This is my the correct curl format that has success result from the API, but with file I have in my desktop:
curl -F file=#/Users/dedenbangkit/Desktop/testing.zip
-u email#email.com
-F 'data={"title":"API V1 App","version":"0.1.0","create_method":"file"}'
https://build.phonegap.com/api/v1/apps
As mentioned before, you cannot use multipart and json together.
In your curl example it's just a multipart form, so use the same in Guzzle:
$this->client->request('POST', 'apps', [
'multipart' => [
[
'name' => 'file',
'contents' => fopen($zip_path, 'r'),
],
[
'name' => 'data',
'contents' => json_encode(
[
'title' => $request->title,
'create_method' => 'file',
'share' => 'true',
'private' => 'false',
]
),
]
]
]);

Resources