GOOGLE ADS

miércoles, 4 de mayo de 2022

Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección.

Tengo algunos requestsdocumentos que pueden presentar una subcolección llamada status. Mis reglas actuales son algo así:

rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {

// I use it to check if user is signed in
function userSignedIn() {
return request.auth!= null;
}

match /requests/{requestId} {

// I use it to check if user is the owner of the request
function userCanAccess () {
return userSignedIn() && request.auth.uid == get(/databases/$(database)/documents/requests/$(requestId)).data.userId;
}


// allow read to logged user who own request
allow read, update: if userCanAccess();

// anyone can create a new request
allow create: if true;

// no one can delete the request
allow delete: if false;



match /status/{statusId} {
// allow read and update of status to logged user who own request
allow read, update: if userCanAccess();

// anyone can create the status
allow create: if true;

// no one can delete the status
allow delete: if false;
}
}
}
}

Mi primera forma de verificar si el usuario tenía acceso fue por request.auth.uid == resource.data.userId, sin embargo, solo funciona para requestsdocumentos, no para statusdocumentos, ya que no tienen el userIdcampo.

Estoy usando flutter para hacer la solicitud con el código:

FirebaseFirestore.instance
.collection('requests')
.where('userId', isEqualTo: user.uid)
.orderBy('requestedOn', descending: true)
.snapshots()
.listen((snapshot) {
// Here I read requests and their status
});

Sin embargo, estoy recibiendo Error: [cloud_firestore/permission-denied] Missing or insufficient permissions.. ¿Cómo puedo resolverlo (o depurarlo)? Usando las reglas del patio de recreo en firestore, con exactamente lo mismo uid, puedo completar la lectura.


Solución del problema


Me pregunto si la get()llamada puede estar causando problemas. Prueba esto:

function userCanAccess () {
return userSignedIn() && request.auth.uid == requestId.data.userId;
}

WSL: ¿por qué falla Maven?

Estoy usando WSL (Ubuntu shell) en Windows. Instalé Java y Maven y una vez que ejecuto Maven desde el shell de Ubuntu obtengo:

$ mvn
[ERROR] Error executing Maven.
[ERROR] java.lang.IllegalStateException: Unable to load cache item
[ERROR] Caused by: Unable to load cache item
[ERROR] Caused by: Could not initialize class com.google.inject.internal.cglib.core.$MethodWrapper

Por supuesto, no sucede una vez que ejecuto Maven desde el shell de Windows "normal".

Sabes que puedo hacer para solucionarlo?

Edit:
$ echo $JAVA_HOME
/usr/lib/jvm/java-17-openjdk-amd64
$ java -version
openjdk version "17.0.2" 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-Ubuntu-120.04)
OpenJDK 64-Bit Server VM (build 17.0.2+8-Ubuntu-120.04, mixed mode, sharing)
$ mvn -version
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.2, vendor: Private Build, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en, platform encoding: UTF-8
OS name: "linux", version: "5.10.16.3-microsoft-standard-wsl2", arch: "amd64", family: "unix"


Solución del problema

Gracias a @ Turing85 por referirme al error.

Me quedé con Java 17, pero descargué la versión 3.8.5 de Maven.

Puede ver una explicación aquí sobre cómo hacerlo:
https://websiteforstudents.com/how-to-install-apache-maven-on-ubuntu-linux/

Error de referencia: el tipo no está definido en React.js [cerrado]

Cerrado. Esta pregunta no es reproducible o fue causada por errores tipográficos. Actualmente no está aceptando respuestas.


Solución del problema

Supongo que la switchafirmación es incorrecta. La instrucción Switch debe tener solo una expresión.

Creo que debería seraction.type

switch(action.type)

Obteniendo el error "NotSameOriginAfterDefaultedToSameOriginByCoep" con Helmet

Veo el siguiente error en la consola de mi navegador cuando uso Helmet.js:

 net::ERR_BLOCKED_BY_RESPONSE.NotSameOriginAfterDefaultedToSameOriginByCoep

¿Qué tengo que hacer?


Solución del problema

tl; dr: deshabilite el Cross-Origin-Embedder-Policyencabezado, habilitado de forma predeterminada en Helmet v5.

app.use(
helmet({
crossOriginEmbedderPolicy: false,
//...
})
);

Helmet v5 establece el encabezado de Cross-Origin-Embedder-Policyrespuesta HTTP en require-corp. (Esto era posible en Helmet v4, pero estaba desactivado de forma predeterminada, por lo que la mayoría de la gente no lo usaba).

Establecer este encabezado significa que cargar recursos de origen cruzado (como una imagen de otro recurso) es más complicado. Por ejemplo, cargar un origen cruzado como este...

<img alt="My picture" src="https://example.com/image.png">

... no funcionará a menos example.comque lo permita explícitamente, estableciendo algunos encabezados de respuesta propios. Su navegador intentará cargar example.com/image.pngy, si no está explícitamente permitido, dejará caer la respuesta.

Para solucionar esto, puede evitar que Helmet configure el Cross-Origin-Embedder-Policyencabezado, así:

app.use(
helmet({
crossOriginEmbedderPolicy: false,
//...
})
);

Hice una pequeña aplicación de muestra que puedes usar para jugar con esto. En mis pruebas, no parece funcionar en HTTP, pero sí en HTTPS, lo que podría explicar por qué las cosas solo fallan en producción.

La mutación de consulta de reacción isError no se establece en verdadero en POST fallido

Estoy usando la siguiente solicitud de publicación de búsqueda para crear un elemento en mi base de datos. Estoy tratando de usar react-query para detectar el error arrojado por la solicitud.

export function createItem(id, body, token) {
fetch(`${API_URL}/${id}/items`, {
method: 'post',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
body: JSON.stringify(body)
})
.then(res => {
if (res.ok) {
return res.json()
}
console.log(res.status)
throw new Error("Error creating review")
})
.catch((err) => console.log(err))
}

Tengo la mutación establecida así:

const mutation = useMutation(() => {
return createItem(props.item.id, item, token)
})

Y se llama con:

<Button disabled={!valid} onPress={() => mutation.mutate()}>
Submit
</Button>

Yo uso esta lógica para mostrar el error:

{
mutation.isError && <Text>{mutation.error.message}</Text>
}

Veo los createItemerrores de función con un código de estado 400, que es lo que espero, pero reaccionar-consulta no se establece isErroren verdadero. En cambio isSuccesses cierto. ¿Estoy manejando mal el error de alguna manera?


Solución del problema

Desde los documentos de consulta de reacción, devuelven una promesa a la mutación, así que intente cambiar su función createItema lo siguiente:

export function createItem(id, body, token) {
// return the fetch as a promise
return fetch(`${API_URL}/${id}/items`, {
method: 'post',
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
body: JSON.stringify(body)
})
// remove then and catch here

Resolver múltiples promesas dentro de un observable que no funciona

Estoy usando Firebase Storage y estoy tratando de cargar todos los activos a través de una llamada de función. La única forma de obtener una URL de activos es llamar, getDownloadURLlo que devuelve una promesa. Necesito llamar a esto para cada activo, pero no puedo hacerlo esperar a que se cumplan todas las promesas antes de continuar por alguna razón.

Pensé que devolver una promesa mergeMapharía esperar a todos, pero ese no parece ser el caso.

He mirado una serie de preguntas con respecto a las promesas y RXJS, pero parece que no puedo averiguar qué está mal con el código.

getAssets() {
return this.authService.user$.pipe(
first(),
switchMap(user => defer(() => from(this.afs.storage.ref(`${user.uid}/assets`).listAll()))),
switchMap(assets => from(assets.items).pipe(
mergeMap(async (asset) => {

return new Promise((res, rej) => {

asset.getDownloadURL().then(url => {

const _asset = {
name: asset.name,
url,
};

this.assets.push(_asset);
res(_asset);
})
.catch((e) => rej(e));
});
}),
)),
map(() => this.assets),
);
}
...
this.getAssets().subscribe(assets => console.log(assets)); // this runs before all asset's url has been resolved


Solución del problema


const { from } = rxjs
const { mergeMap } = rxjs.operators
const assets = [1,2,3,4,5]
function getUrl (index) {
return new Promise((res) => {
setTimeout(() => res(`http://example.com/${index}`), Math.random() * 3 + 1000)
})
}
// add param2 1 for mergeMap === concatMap
from(assets).pipe(
mergeMap(asset => {
return getUrl(asset)
}, 1)
).subscribe(console.log)

<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.5.5/rxjs.umd.min.js"></script>

Palabras coincidentes y palabras delimitadas por dos puntos parciales entre paréntesis (excluyendo paréntesis)

Estoy tratando de extraer símbolos bursátiles de un cuerpo de texto. Estos partidos generalmente vienen en las siguientes formas:

(<symbol>) => (VOO)
(<market>:<symbol>) => (NASDAQ:C)

En los casos de muestra que se muestran arriba, me gustaría hacer coincidir VOO y C, omitiendo todo lo demás. Esta expresión regular me lleva a la mitad del camino:

(?<=\()(.*?)(?=\))

Con esto, coincido con lo que está incluido entre paréntesis, pero la lógica que ignora el "ruido" NASDAQ:me elude. Me encantaría aprender a especificar condicionalmente este patrón/lógica.

¿Algunas ideas? ¡Gracias!


Solución del problema

Puedes usar

[A-Z]+(?=\))

Vea la demostración de expresiones regulares.

Detalles:


  • [A-Z]+- una o más letras ASCII mayúsculas

  • (?=\))- una anticipación positiva que coincide con una ubicación seguida inmediatamente por un )carácter.


Alternativamente, puede usar lo siguiente para capturar los valores en el Grupo 1:

\((?:[^():]*:)?([A-Z]+)\)

Vea esta demostración de expresiones regulares. Detalles:


  • \(- un (char

  • (?:[^():]*:)?- una secuencia opcional de cero o más caracteres que no sean (, )y :luego un :carácter

  • ([A-Z]+)- Grupo 1: una o más letras ASCII mayúsculas

  • \)- un )char.

martes, 3 de mayo de 2022

Solicitud de publicación http de Flutter a un archivo PHP

Estoy usando Flutter para el desarrollo de aplicaciones móviles. Necesito hacer una solicitud POST a un archivo PHP para guardar datos en mi servidor MySQL. Sin embargo, verifico el código de estado de la solicitud y parece estar bien (200). Pero, la solicitud falla. Creo que en mi archivo PHP hay un problema porque no me gusta PHP. ¿Alguien puede decirme si el problema está en mi código Flutter o en PHP?

Insertar archivo PHP

<?php

require 'connect.php';
$kayitNo =$_POST['kayit_no'];
$stajTuru=$_POST['staj_turu'];
$yas=$_POST['yas'];
$doktor=$_POST['klinik_egitici'];
$cinsiyet=$_POST['cinsiyet'];
$sikayet=$_POST['sikayet'];
$ayiriciTani=$_POST['ayirici_tani'];
$kesinTani=$_POST['kesin_tani'];
$tedaviYontemi=$_POST['tedavi_yontemi'];
$etkilesimTuru=$_POST['etkilesim_turu'];
$kapsam=$_POST['kapsam'];
$gerceklestigiOrtam=$_POST['ortam'];
$status=$_POST['form_status'];
$tarih=$_POST['tarih'];
echo $kayitNo;
$query="INSERT INTO form_table(kayit_no, staj_turu, yas, klinik_egitici, cinsiyet, sikayet, ayirici_tani,
kesin_tani, tedavi_yontemi, etkilesim_turu, kapsam, ortam, form_status,tarih) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?) ";
$stmt =$conn->prepare($query);
$stmt->bind_param("ssssssssssssss",$kayitNo,$stajTuru,$yas,$doktor,$cinsiyet,$sikayet,$ayiriciTani,
$kesinTani,$tedaviYontemi,$etkilesimTuru,$kapsam,$gerceklestigiOrtam, $status,$tarih);
$stmt->execute();
$error = $conn->error();
if ( empty( $error ) ) {
http_response_code( 201 );
} else {
echo $error;
}
$stmt->close();
$conn->close();
?>

Método HTTP POST (Flutter-Dart)

Future insertFormToDatabase(FormData formData) async{
var url = Uri.parse("http://10.0.2.2/flutter/insert.php");
var response = await http.post(url,
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body:jsonEncode(formData.toMap())
);
if (response.statusCode == 201) {
print("request succ.");
return true;
} else {
print(response.statusCode);
print("request failed.");
return false;
} }

Resultado de la red Flutter DevTools

ingrese la descripción de la imagen aquí

Respuesta

<br />
<b>Warning</b>: Undefined array key "kayit_no" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>6</b><br />
<br />
<b>Warning</b>: Undefined array key "staj_turu" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>7</b><br />
<br />
<b>Warning</b>: Undefined array key "yas" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>8</b><br />
<br />
<b>Warning</b>: Undefined array key "klinik_egitici" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>9</b><br />
<br />
<b>Warning</b>: Undefined array key "cinsiyet" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>10</b><br />
<br />
<b>Warning</b>: Undefined array key "sikayet" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>11</b><br />
<br />
<b>Warning</b>: Undefined array key "ayirici_tani" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>12</b><br />
<br />
<b>Warning</b>: Undefined array key "kesin_tani" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>13</b><br />
<br />
<b>Warning</b>: Undefined array key "tedavi_yontemi" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>14</b><br />
<br />
<b>Warning</b>: Undefined array key "etkilesim_turu" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>15</b><br />
<br />
<b>Warning</b>: Undefined array key "kapsam" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>16</b><br />
<br />
<b>Warning</b>: Undefined array key "ortam" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>17</b><br />
<br />
<b>Warning</b>: Undefined array key "form_status" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>18</b><br />
<br />
<b>Warning</b>: Undefined array key "tarih" in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>19</b><br />
<br />
<b>Fatal error</b>: Uncaught mysqli_sql_exception: Column 'kayit_no' cannot be null in C:\xampp\htdocs\flutter\insert.php:28
Stack trace:
#0 C:\xampp\htdocs\flutter\insert.php(28): mysqli_stmt-&gt;execute()
#1 {main}
thrown in <b>C:\xampp\htdocs\flutter\insert.php</b> on line <b>28</b><br />


Solución del problema

¿Me lo estoy perdiendo? Parece que olvidaste agregar $stmt->execute();tu código PHP. Iría después $stmt->bind_param(...);y antes $stmt->close();. Preparó la declaración pero nunca la ejecutó. Esa podría ser la razón por la que no va a la base de datos.

Para devolver un 201 en caso de éxito, puede intentar esto justo después $stmt->execute();:

$error = $conn->error();
if ( empty( $error ) ) {
http_response_code( 201 );
} else {
// However you want to handle an error. Maybe echo $error here?
}

Problema con la aplicación del servidor blazor con autenticación de Azure AD que llama a una API web segura con un token de portador

Creé una API web que requiere autorización y se implementa en una aplicación web de Azure. También tengo una aplicación Blazor Server que requiere autenticación de Azure AD.

Cuando ejecuto la aplicación Blazor Server desde Visual Studio, puede obtener un token y llamar correctamente a la API web implementada en Azure.

Sin embargo, cuando implemento la aplicación Blazor Server en una aplicación web de Azure, aparece un error 401 cuando llama a la API web, a pesar de que funcionó desde Visual Studio.

Así es como configuro el token antes de la llamada a la API web

 var accessToken = await _authRepo.PrepareAuthenticatedClient();
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

incluyendo también una captura de la excepción

@inject MicrosoftIdentityConsentAndConditionalAccessHandler ConsentHandler

 catch (Exception ex)
{
ConsentHandler.HandleException(ex);
}

Este procedimiento obtiene un token para el usuario que inició sesión para el alcance de la API web:

public async Task<string> PrepareAuthenticatedClient()
{
var accessToken = await _tokenAcquisition.GetAccessTokenForUserAsync(new[] { _WPScope });
return accessToken;
}

Este es el código en el archivo startup.cs

 public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"))
.EnableTokenAcquisitionToCallDownstreamApi(new string[] { "api://xxxxxxxxxxxxxxxxxxxxxx/allaccess" })
.AddInMemoryTokenCaches();
services.AddControllersWithViews(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
}).AddMicrosoftIdentityUI();


¿Cómo configuro esto en Azure para que funcione como lo hace en Visual Studio?


Solución del problema

Por favor, intente estos:

  • Después de descodificar el token, si ve la URL del emisor con el punto de conexión v2, asegúrese de cambiar la versión aceptada del token de acceso a 2 en el manifiesto en Azure Ad Portal, si el valor iss tiene un cambio de punto de conexión v1 en el manifiesto a 1.

  • Además, si lo anterior no es la causa, vea si la audiencia, es decir; aud reclamación es igual a la identificación del cliente. De lo contrario, intente cambiar el alcance al no incluir el prefijo api://.

  • Y también asegúrese de que los permisos de la API tengan el consentimiento.

    Cable Laravel Livewire: haga clic en no disparar

    Estoy trabajando en una plataforma de comercio electrónico basada en Laravel y Livewire usando el carrito de compras bumbummen99. Mi problema es que solo puedo agregar artículos al carrito, pero por alguna razón no puedo actualizar (aumentar o disminuir) la cantidad, eliminar un artículo del carrito. No tengo ningún error en la consola, no hay actividad de red al hacer clic en cualquiera de los botones. He comprobado que todo el HTML está encerrado en uno <div>. Revisé un par de otras páginas ( aquí, aquí, aquí ) pero no tuve suerte. También intenté cambiar el cable que no funciona: haga clic para seguir el formato del cable: haga clic en agregar al carrito que funciona, eso tampoco ayudó. Cualquier ayuda es muy apreciada.

    Aquí está mi tabla de listado de productos

    @extends('layouts.app')
    @section('template_linked_css')
    <link href="{{asset('front/css/cart.css')}}" rel="stylesheet">
    @endsection
    @section('content')
    <main class="bg_gray">
    @livewire('cart-listing')
    </main>
    @endsection

    Aquí está mi componente CartListing:

    use App\Models\Service;
    use Gloudemans\Shoppingcart\Facades\Cart;
    use Livewire\Component;
    class CartListing extends Component
    {
    public $products;
    public array $quantity = [];
    public function mount()
    {
    $this->products = Cart::content();
    foreach ($this->products as $product) {
    $this->quantity[$product->id] = 1;
    }
    }
    public function addToCart($product_id)
    {
    $product = Product::findOrFail($product_id);
    Cart::add(
    $product->id,
    $product->name,
    $this->quantity[$product_id],
    $product->price
    );
    $this->emit('cart_updated');
    }
    public function increase($rowId){
    Cart::update($rowId, 1);
    $this->emit('cart_updated');
    }
    public function decrease($rowId){
    Cart::update($rowId, -1);
    $this->emit('cart_updated');
    }
    public function deleteItem($rowId){
    Cart::remove($rowId);
    $this->emit('cart_updated');
    }
    public function render()
    {
    $cart = Cart::content();
    $cart_count = Cart::content()->count();
    $cart_total = Cart::subtotal();
    return view('livewire.cart-listing', compact('cart', 'cart_count', 'cart_total'));
    }
    }

    Aquí está mi vista de lista de carritos de Livewire:

    <div>
    <div class="container margin_30">
    <div class="page_header">
    <div class="breadcrumbs">
    <ul>
    <li><a href="#">Home</a></li>
    <li>Cart</li>
    </ul>
    </div>
    <h1>Cart</h1>
    </div>
    <!-- /page_header -->
    <table class="table table-striped cart-list">
    <thead>
    <tr>
    <th>
    Product
    </th>
    <th>
    Price
    </th>
    <th>
    Quantity
    </th>
    <th>
    Subtotal
    </th>
    <th>
    </th>
    </tr>
    </thead>
    <tbody>
    @forelse ($products as $product)
    <tr>
    <td>
    <div class="thumb_cart">
    <img src="{{asset('front/img/products/product_placeholder_square_small.jpg')}}" data-src="{{asset('front/img/products/shoes/1.jpg')}}" class="lazy" alt="Image">
    </div>
    <span class="item_cart">{{$product->name}}</span>
    </td>
    <td>
    <strong>£ {{$product->price}}</strong>
    </td>
    <td>
    <div class="numbers-row">
    <input type="text" value="{{$product->qty}}" id="quantity_1" class="qty2" name="quantity_1">
    <div wire:click="increase({{$product->rowId}})" class="inc button_inc">+</div>
    <div wire:click="decrease({{$product->rowId}})" class="dec button_inc">-</div>
    </div>
    </td>
    <td>
    <strong>£ {{number_format($product->price * $product->qty, 2,'.',',')}}</strong>
    </td>
    <td class="options">
    <a wire:click="deleteItem({{$product->rowId}})"><i class="ti-trash"></i></a>
    </td>
    </tr>
    @empty
    <tr>
    <td colspan="3">
    <span class="item_cart">Your cart is empty</span>
    </td>
    </tr>
    @endforelse
    </tbody>
    </table>
    </div>
    <!-- /container -->
    <div class="box_cart">
    <div class="container">
    <div class="row justify-content-end">
    <div class="col-xl-4 col-lg-4 col-md-6">
    <ul>
    <li>
    <span>Subtotal</span> $ {{$cart_total}}
    </li>
    <li>
    <span>Total</span> $ {{$cart_total}}
    </li>
    </ul>
    <a href="cart-2.html" class="btn_1 full-width cart">Proceed to Checkout</a>
    </div>
    </div>
    </div>
    </div>

    </div>

    Mi layouts.app también tiene los enlaces livewire:

    <head>
    @livewireStyles
    </head>
    <body >
    @livewireScripts
    </body>


    Solución del problema

    Si está pasando una cadena al wire:clickmétodo, debe encapsularla con comillas simples como esta

    wire:click="increase('{{$product->rowId}}')"

    Replaykit - La grabación no comienza Error- 5803

    Quiero empezar a grabar en mi App, estoy usando ReplayKit

    func startRecordn(){
    recorder.startRecording{ [unowned self] (error) in
    //2
    guard error == nil else {
    print("There was an error starting the recording.")
    return
    }
    //3
    print("Started Recording Successfully")
    }
    }

    Cada vez que me sale el error

    Domain=com.apple.ReplayKit.RPRecordingErrorDomain Code=-5803 "Error al iniciar la grabación" UserInfo={NSLocalizedDescription=Error al iniciar la grabación} Hubo un error al iniciar la grabación.


    Solución del problema

    Finalmente encontré el problema, en mi AppDelegate, debajo del problema creado por el código, lo comenté y obtuve el aviso de permiso

     if #available(iOS 13, *) {
    window = UIWindow(frame: UIScreen.main.bounds)

    Llamada de cierre con argumentos no coincidentes: función '_TaskTileState.checkboxCallback'

    Estoy recibiendo este error en mi código

    ======== Exception caught by widgets library =======================================================
    The following NoSuchMethodError was thrown building TaskCheckbox(dirty):
    Closure call with mismatched arguments: function '_TaskTileState.checkboxCallback'
    Receiver: Closure: (bool) => void from Function 'checkboxCallback':.
    Tried calling: _TaskTileState.checkboxCallback()
    Found: _TaskTileState.checkboxCallback(bool) => void
    The relevant error-causing widget was:
    TaskCheckbox TaskCheckbox:file:///F:/Code/Flutter/todoey_flutter/lib/widgets/task_tile.dart:28:17
    When the exception was thrown, this was the stack:
    #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
    #1 _objectNoSuchMethod (dart:core-patch/object_patch.dart:106:9)
    The relevant error-causing widget was:
    TaskCheckbox TaskCheckbox:file:///F:/Code/Flutter/todoey_flutter/lib/widgets/task_tile.dart:28:17
    When the exception was thrown, this was the stack:
    #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
    #1 _objectNoSuchMethod (dart:core-patch/object_patch.dart:106:9)

    Aquí está mi código que a través de este error

     // ignore_for_file: prefer_const_constructors
    import 'package:flutter/material.dart';
    class TaskTile extends StatefulWidget {
    @override
    State<TaskTile> createState() => _TaskTileState();
    }
    class _TaskTileState extends State<TaskTile> {
    bool isChecked = false;
    void checkboxCallback(bool checkboxState) {
    setState(() {
    isChecked = checkboxState;
    });
    }
    @override
    Widget build(BuildContext context) {
    return ListTile(
    title: Text(
    'This is task',
    style: TextStyle(
    decoration: isChecked? TextDecoration.lineThrough: null,
    ),
    ),
    trailing: TaskCheckbox(isChecked, checkboxCallback),
    );
    }
    }
    class TaskCheckbox extends StatelessWidget {
    final bool checkboxState;
    final Function toggleCheckboxState;
    TaskCheckbox(this.checkboxState, this.toggleCheckboxState);
    @override
    Widget build(BuildContext context) {
    return Checkbox(
    activeColor: Colors.lightBlueAccent,
    value: checkboxState,
    onChanged: toggleCheckboxState(),
    );
    }
    }

    Estoy tratando de crear un estado global para intercambiar datos entre dos clases diferentes y cambiar el estado en la pantalla.


    • esta es una aplicación de gestión de tareas en la que obtengo los datos de una variable estática. Quiero intercambiar valores booleanos entre dos clases y mostrar la lista de tareas de acuerdo con ese valor booleano.*
      ¿Puede alguien ayudarme con esto?



    Solución del problema

    import 'package:flutter/material.dart';
    class TaskTile extends StatefulWidget {
    @override
    State<TaskTile> createState() => _TaskTileState();
    }
    class _TaskTileState extends State<TaskTile> {
    bool isChecked=false;
    void CheckBoxCallback(bool? checkboxstate){
    setState(() {
    isChecked = checkboxstate!;
    });
    }
    @override
    Widget build(BuildContext context) {
    return ListTile(
    title: Text('baking today',
    style: TextStyle(
    decoration: isChecked?TextDecoration.lineThrough:null),),
    trailing: TaskCheckBox(
    checkboxstate: isChecked,
    togglecheckboxstate: CheckBoxCallback,

    ),
    );
    }
    }
    class TaskCheckBox extends StatelessWidget {
    final bool checkboxstate;
    final Function(bool?)? togglecheckboxstate; // Here is where to make changes, observe the "bool?" i added.
    TaskCheckBox({required this.checkboxstate,required this.togglecheckboxstate});
    @override
    Widget build(BuildContext context) {
    return Checkbox(
    value: checkboxstate,
    onChanged:togglecheckboxstate, // and here too on your code
    );
    }
    }

    Creando miles de filas en la base de datos con Spring Data

    Tengo un servicio Spring Boot donde tenemos proyectos, colaboradores y una relación de muchos a muchos entre proyectos y colaboradores, esto se modela en JPA como 3 entidades separadas, Project, Contributor y ProjectContributor. Estoy usando Spring Data para interactuar con la base de datos que está en Postgres.

    Tras el consumo de un evento de SQS, hay momentos en los que tenemos que crear miles de proyectos en la base de datos junto con sus colaboradores. Estos proyectos y colaboradores son proporcionados por algunos servicios externos.

    En el escenario en el que tenemos que crear 1000 proyectos y cada proyecto tiene un promedio de 2 colaboradores, realizo las siguientes llamadas a la base de datos a través de los métodos de guardado del repositorio Spring Data para cada entidad.

    1000 llamadas al método ProjectRespository.save() para crear proyectos

    2000 llamadas al método ContributorRespository.save() para crear colaboradores

    2000 llamadas al método ProjectContributorRespository.save() para asociar colaboradores a proyectos

    Y ni siquiera estoy contando que antes de crear un colaborador, tengo que emitir una consulta para verificar si el colaborador ya existe en la base de datos.

    Todo esto está dentro de un método @Transactional. Esta lógica tarda una eternidad en completarse, me preguntaba cuál es el mejor enfoque para hacer algo como esto en Spring Boot y Spring Data para reducir significativamente la cantidad de llamadas a la base de datos para crear los objetos mencionados anteriormente.


    Solución del problema

    Esto suena como una buena opción para el procesamiento por lotes de inserciones. En pocas palabras, puede realizar muchas inserciones en un viaje de ida y vuelta de DB. El procesamiento por lotes es configurable por la propiedad hibernate.jdbc.batch_size. Vale la pena señalar que el lote se dirige solo a una tabla. Entonces, 5 inserciones en la tabla Project, 5 en Contributor, luego, una vez más, 5 en Project y 5 en Contributor se realizarán en 4 lotes. Es mejor hacer 10 inserciones en Project y 10 en Contributor u ordenar las inserciones a través de la propiedad hibernate.order_inserts. Entonces solo tiene 2 viajes de ida y vuelta de DB en el caso mencionado anteriormente. Puede leer más sobre esto en https://vladmihalcea.com/how-to-batch-insert-and-update-statements-with-hibernate/.

    ¿Cómo agregar un meta/comentario a una secuencia definida a través de def en Clojure?

    Tuve que comentar la línea a continuación (el ejemplo es de http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci )

    (def fib-seq
    ;"Implements Fibonacci sequence (starts with 0)."
    ((fn rfib [a b]
    (lazy-seq (cons a (rfib b (+ a b)))))
    0 1))

    Si lo dejara dentro, obtendría:

    Clojure 1.2.0
    java.lang.Exception: Too many arguments to def (Problem1.clj:1)
    1:1 user=>

    Puedo hacer esto con defn, sin embargo. Ejemplo (lo sé, estoy reinventando la rueda porque even?ya está definido):

    (defn is-even? [n]
    "Returns true if the number is even, false otherwise."
    (== (mod n 2) 0))
    Clojure 1.2.0
    1:1 user=> (is-even? 3)
    false
    1:2 user=> (is-even? 4)
    true
    1:3 user=>


    Solución del problema

    (def ^{:doc "Implements Fib. sequence lazily."} fibs...)

    (:doc (meta (var fibs)))

    ; "Implements Fib. sequence lazily."

    Es bastante simple escribir una macro para que puedas escribir (def-with-docs foo "doc" 1).

    (defmacro def-with-docs [name docstring value]
    `(def ~(with-meta name {:doc docstring}) ~value))
    (def-with-docs fib-seq "Implements Fibbonaci sequence (starts with 0)."
    ((fn rfib [a b] (lazy-seq (cons a (rfib b (+ a b))))) 0 1))

    (:doc (meta (var fib-seq)))

    ; "Implements Fibbonaci sequence (starts with 0)."

    Además, tenga en cuenta que con su ejemplo de uso de defn, la cadena de documentación debe preceder a los argumentos; de lo contrario, no se asociará con los metadatos del símbolo.

    Alternativamente, se puede usar clojure.contrib.def/defvar.

    No capturado (en promesa) TypeError: no se pueden leer las propiedades de nulo (leyendo 'useState')

    No puedo entender por qué recibo este error en const [isLoading, setLoading] = useState(true); Se declara como verdadero desde el principio, así que no puedo entender cómo es que nunca está definido

    export default async function GetProducts() {
    const [isLoading, setLoading] = useState(true);
    const [products, setProducts] = useState([]);
    useEffect(() => {
    if (isLoading) {
    let url = 'http://127.0.0.1:8000/products'
    const res = axios.get(url);
    let data = res.json()
    }});
    if (isLoading) {
    return GetLoadingScreen()
    } else {
    return RenderProducts(products)
    }
    }


    Solución del problema

    Considere no marcar la función del componente React como asíncrona y marcar la función creada useEffectcomo asíncrona en su lugar.

    export default function GetProducts() {
    const [isLoading, setLoading] = useState(true);
    const [products, setProducts] = useState([]);
    useEffect(async () => {
    if (isLoading) {
    let url = 'http://127.0.0.1:8000/products'
    const res = await axios.get(url);
    let data = res.json()
    }});
    if (isLoading) {
    return GetLoadingScreen()
    } else {
    return RenderProducts(products)
    }
    }

    ¿Por qué se usa get () en este ejemplo de viewBinding?

    ¡Quiero saber por qué "enlace de valor privado get () = _enlace!" se usó aquí?

     private var _binding: ResultProfileBinding? = null
    private val binding get() = _binding!!
    override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
    ): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
    }
    override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
    }


    Solución del problema

    Supongo que obtuviste ese código de esta página en la documentación.

    Su objetivo es brindarle una forma de acceder al _bindingvalor sin tener que lidiar con el hecho de que _bindingpuede ser null. En la parte de su ejemplo que no incluyó, tienen un comentario bindingque señala que solo se puede usar entre onCreateView()y onDestroyView(). Si se encuentra en una parte de su código en la que puede garantizar que su código se ejecutará entre esas dos devoluciones de llamada, puede hacer referencia a binding, que devolverá el valor de _bindingforzado a un nulltipo no ( ResultProfileBindingen lugar de ResultProfileBinding?).

    Sin embargo, si se equivoca e intenta hacer referencia bindingantes onCreateView()o después onDestroyView()de, se bloqueará con un archivo NullPointerException.

    Personalmente, evitaría este enfoque.

    ¿Debo usar una máquina de estado o un flujo de trabajo de secuencia en WF?

    Tengo un proceso comercial repetible que ejecuto todas las semanas como parte de mis responsabilidades de gestión de la configuración. El proceso no cambia: descargo los detalles del cambio en Excel, abro la hoja de cálculo y copio los detalles en función de una macro, creo un documento de Word a partir de una plantilla de agenda, actualizo la agenda con los datos de Excel, creo archivos PDF a partir del documento de Word y enviarlos por correo electrónico.

    Este proceso se representa muy fácilmente en un flujo de trabajo de secuencia y así es como lo tengo hasta ahora, con automatización COM para manejar las piezas de Excel y Word automáticamente. La llave en los engranajes es que hay un paso humano entre "crear agenda" y "enviarla", donde reviso los detalles del cambio y formulo preguntas sobre ellos, que se agregan a la agenda. Actualmente tengo una actividad Suspender para suspender el flujo de trabajo mientras realizo manualmente esta parte del proceso.

    Mi pregunta es, ¿debería reescribir mi flujo de trabajo para convertirlo en una máquina de estado para seguir una mejor práctica para la interacción humana en un proceso comercial, o la actividad Suspender es una solución razonable?


    Solución del problema

    No, no creo que tengas que usar una máquina de estado para este flujo de trabajo. Pero propongo cambiar la actividad Suspender porque:

    La actividad SuspendActivity detiene temporalmente la ejecución del flujo de trabajo actual. Normalmente, utiliza la actividad SuspendActivity para reflejar una condición de error que requiere la atención de un administrador.


    Cuando se suspende una instancia de flujo de trabajo, se registra un error. Puede especificar una cadena de mensaje para acompañar el error para ayudar al administrador a diagnosticar el problema con la propiedad SuspendActivity Error. Una instancia de flujo de trabajo suspendida aún puede recibir mensajes que están en cola hasta que se reinicia el flujo de trabajo. Toda la información de estado de la instancia de flujo de trabajo se guarda y se restablece cuando se reanuda la instancia (usando Reanudar).


    Fuente: MSDN

    La forma típica de agregar una tarea humana en un flujo de trabajo (ya sea una secuencia o una máquina de estado) es definir una interfaz de intercambio de datos externos y usar una actividad HandleExternalEvent (y posiblemente una actividad CallExternalMethod). Para obtener más detalles, consulte los siguientes artículos:


    • Creación de máquinas de estado con Windows Workflow Foundation

    • Flujo de trabajo humano simple con Windows Workflow Foundation

    Tabla dinámica Campo calculado - Sumif(s) entre dos fechas?

    Estoy tratando de calcular los períodos de desabastecimiento de una flota de equipos de alquiler que ha estado en servicio durante los últimos años. Tengo problemas para crear un campo calculado sumif que sume unidades por fecha si la fecha está entre el inicio y el final. Mis datos se ven así:

    Calendar |Start |Finish |Product |Units
    2015-12-06|2015-12-6|2015-12-6 |Snowshoes |2
    2015-12-07|2015-12-6|2015-12-7 |Snowshoes |1

    Calendario: es una columna de ayuda que he agregado. Son fechas secuenciales desde el lanzamiento hasta el presente Inicio: es la fecha de inicio de una reserva de alquiler Finalización: fecha de finalización de la reserva de alquiler Producto: qué se alquila Unidades: cuántas se alquilan para esa reserva

    Me gustaría que la tabla dinámica se vea así:

    Date | Snowshoes | Tent... etc
    2015-12-06 | 3 |
    2015-12-07 | 1 |

    Tengo dificultades para configurar un campo calculado que sumará unidades si la fecha está entre el inicio y el final, sigo recibiendo errores de fórmula.

    Aquí está la fórmula que intento usar para crear un campo calculado:

    = sumifs( Units,Start,">= Calendar", Finish,"<= Calendar")

    ¿Es esta la mejor manera de resolver este problema? ¿Es mi fórmula el problema o todo el enfoque es defectuoso?

    Agregando capturas de pantalla:
    ingrese la descripción de la imagen aquí

    ingrese la descripción de la imagen aquí

    ingrese la descripción de la imagen aquí


    Solución del problema

    De los datos que tienes en las capturas de pantalla, esto es lo que se me ocurrió.

    La fórmula a utilizar en column G:

    =SUMIFS($E$2:$E$29,$A$2:$A$29,"<="&F2,$B$2:$B$29,">="&$F2)

    La fórmula a usar en column H(Por cierto, esto es solo para su referencia. Puede usar cualquiera de ellos):

    =SUMPRODUCT(--($A$2:$A$29<=F2),--($B$2:$B$29>=F2),$E$2:$E$29)

    A partir de aquí, creé algo Pivot Tableasí:

    Espero que esto pueda ayudarte. Pero definitivamente avíseme si me pierdo algo de su pregunta.

    React Router v5: history.push() cambia la barra de direcciones, pero no cambia la página

    Estoy tratando de redirigir a un usuario a una nueva página si un inicio de sesión es exitoso en mi aplicación React. La redirección se llama desde el servicio de autenticación que no es un componente. Para acceder al objeto de historial fuera de mi componente, seguí este ejemplo en las preguntas frecuentes de React Router. Sin embargo, cuando llamo history.push('/pageafterlogin'), la página no cambia y permanezco en la página de inicio de sesión (según mi Switchesperanza, esperaría terminar en la 404página). La URL en la barra de direcciones se cambia, /pageafterloginpero la página no cambia desde la página de inicio de sesión. No aparecen errores en la consola ni nada más que indique que mi código no funciona.

    ¿Cómo puedo history.push()cambiar también la página en la que se encuentra el usuario?

    // /src/history.js
    import { createBrowserHistory } from 'history';
    export default createBrowserHistory();
    // /src/App.js
    ...
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import history from './history';
    function App() {
    return (
    <Router history={history}>
    <Switch>
    <Route path="/" exact component={HomePage} />
    <Route path="/login" exact render={() => <FormWrapper><LoginForm /></FormWrapper>} />
    <Route render={() => <h1>404: not found</h1>} />
    </Switch>
    </Router>
    );
    }
    export default App;
    // src/services/auth.service.js
    import axios from 'axios';
    import history from '../history';
    const API_URL = '...';
    class AuthService {
    login(username, password) {
    return axios.post(API_URL + 'login', {
    username,
    password
    }).then(res => {
    if (res.status === 200) {
    localStorage.setItem('user', JSON.stringify(res.data));
    history.push('/pageafterlogin');
    }
    });
    }
    }


    Solución del problema

    En lugar de usar BrowserRouter, use Routerfromreact-router-dom

    Puedes ver el ejemplo aquí


    import { Router, Route, Switch, useHistory, create } from 'react-router-dom';
    import { createBrowserHistory } from 'history';
    import React from 'react';
    const history = createBrowserHistory();
    export default function App() {
    return (
    <Router history={history}>
    <Switch>
    <Route path="/" exact component={() => <h1>HomePage</h1>} />
    <Route path="/login" exact component={Login} />
    <Route render={() => <h1>404: not found</h1>} />
    </Switch>
    </Router>
    );
    }
    function Login() {
    React.useEffect(() => {
    history.push('/pageafterlogin')
    }, [])
    return <h1>Login page</h1>
    }

    ¿Cómo inicializo una estructura en C?

    Recibí un comentario sobre cómo inicializo mi estructura en C, diciendo que no funciona y tampoco compila.

    Así es como creo e inicializo una estructura en C.

    struct {
    int a;
    int b;
    char arr[3];
    .
    .
    .
    } data = {
    .a = 1,
    .b = 2
    };
    main(){
    /* do stuff */
    }

    Así es como inicializo mi estructura y funciona y compila. Sin embargo, recibí un comentario que decía que esto se compilaría para c ++ pero no para C. ¿Alguien puede asegurarme que esta alternativa es correcta? Si no, ¿por qué está compilando sin errores?


    Solución del problema

    Creo que hay un error tipográfico en la declaración del miembro de datos arr. En vez de

    char [3]arr;

    tu tienes que escribir

    char arr[3];

    No puede inicializar una matriz con llaves vacías. Así que escribe por ejemplo

    struct {
    int a;
    char arr[3];
    .
    .
    .
    } data = {
    .a = 1,
    .arr = { 0 }
    };

    De hecho, es suficiente para escribir

    struct {
    int a;
    char arr[3];
    .
    .
    .
    } data = {
    .a = 1
    };

    La matriz implícitamente se inicializará con ceros.

    Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

    Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...